EasyNetQ-用于使用 RabbitMQ 的 .NET API開源的工具庫(kù)
Part1介紹
EasyNetQ 的目標(biāo)是提供一個(gè)庫(kù),用于在 .NET 中使用 RabbitMQ 盡可能簡(jiǎn)單。為了做到這一點(diǎn),它通過(guò)強(qiáng)制執(zhí)行一些簡(jiǎn)單的約定來(lái)以靈活性換取簡(jiǎn)單性。這些包括:
消息應(yīng)該由 .NET 類型表示。消息應(yīng)按其 .NET 類型進(jìn)行路由。這意味著消息是由 .NET 類定義的。您要發(fā)送的每種不同的消息類型都由一個(gè)類表示。該類必須是公共的,必須具有默認(rèn)構(gòu)造函數(shù)和公共讀/寫屬性。您通常不會(huì)在消息中實(shí)現(xiàn)任何功能,而是將其視為簡(jiǎn)單的數(shù)據(jù)容器或數(shù)據(jù)傳輸對(duì)象 (DTO)。
默認(rèn)情況下,EasyNetQ 使用 Newtonsoft.Json 庫(kù)將 .NET 類型序列化為 JSON。
Part2API設(shè)計(jì)

EasyNetQ 是在 RabbitMQ.Client 庫(kù)之上提供服務(wù)的組件集合。它們執(zhí)行序列化、錯(cuò)誤處理、線程編組、連接管理等操作。它們由 mini-IoC 容器組成。您可以很容易地用您自己的實(shí)現(xiàn)替換任何組件。因此,如果您想要 XML 序列化而不是內(nèi)置 JSON,只需編寫 ISerializer 的實(shí)現(xiàn)并將其注冊(cè)到容器中。
這些組件以 IAdvancedBus API 為前端。這看起來(lái)很像 AMQP 規(guī)范,實(shí)際上您可以從這個(gè) API 運(yùn)行大多數(shù) AMQP 方法。此 API 對(duì)您隱藏的唯一 AMQP 概念是通道。這是因?yàn)橥ǖ朗且粋€(gè)令人困惑的低級(jí)概念,一開始就不應(yīng)該成為 AMQP 規(guī)范的一部分。老實(shí)說(shuō),“高級(jí)”對(duì)于這個(gè) API 來(lái)說(shuō)并不是一個(gè)很好的名字,“Iamqp”會(huì)好得多。
位于高級(jí) API 之上的是一組消息傳遞模式:發(fā)布/訂閱、請(qǐng)求/響應(yīng)和發(fā)送/接收。這是 EasyNetQ 的“主見(jiàn)”部分。這是我們對(duì)如何實(shí)施這些模式的看法。靈活性很小;要么你接受我們的做事方式,要么你不使用它。目的是您,用戶,不必花費(fèi)腦力去重新發(fā)明相同的模式;您不必在每次只想發(fā)布和訂閱消息時(shí)都做出選擇。它旨在實(shí)現(xiàn) EasyNetQ 的核心目標(biāo),即盡可能輕松地使用 RabbitMQ。
這些模式位于 IBus API 后面。再一次,這是一個(gè)糟糕的名字,它與消息總線的概念幾乎沒(méi)有關(guān)系。更好的名稱是 IPackagedMessagePatterns。
IBus 旨在為 80% 的用戶、80% 的時(shí)間工作。這并不詳盡。如果您要實(shí)現(xiàn)的模式不是由 IBus 提供的,那么您應(yīng)該使用 IAdvancedBus。這樣做沒(méi)有問(wèn)題,EasyNetQ 就是這樣設(shè)計(jì)的。
Part3為什么我需要 EasyNetQ?
RabbitMQ 不是已經(jīng)有 .NET 客戶端了嗎?
那么為什么我需要 EasyNetQ?RabbitMQ .NET 客戶端實(shí)現(xiàn)了 AMQP 協(xié)議的客戶端(而 RabbitMQ 實(shí)現(xiàn)了服務(wù)器端)。AMQP 旨在作為消息傳遞的 HTTP。它被設(shè)計(jì)成跨平臺(tái)和語(yǔ)言無(wú)關(guān)的。它還旨在靈活地支持基于 Exchange/Binding/Queue 模型的各種消息傳遞模式。
擁有這種靈活性很棒,但隨著靈活性而來(lái)的是復(fù)雜性。這意味著您需要編寫大量代碼才能實(shí)現(xiàn) RabbitMQ 客戶端。通常,此代碼將包括:
實(shí)現(xiàn)消息傳遞模式,例如發(fā)布/訂閱或請(qǐng)求/響應(yīng)。雖然,公平地說(shuō),.NET 客戶端確實(shí)在這里提供了一些支持。實(shí)施路由策略。您將如何設(shè)計(jì)交換隊(duì)列綁定,以及如何在生產(chǎn)者和消費(fèi)者之間路由消息?實(shí)現(xiàn)消息序列化/反序列化。您將如何將 AMQP 中消息的二進(jìn)制表示轉(zhuǎn)換為您的編程語(yǔ)言可以理解的內(nèi)容?為訂閱實(shí)現(xiàn)消費(fèi)者線程。您需要有一個(gè)專門的消費(fèi)者循環(huán)來(lái)等待您訂閱的消息。您將如何處理多個(gè)訂閱者或臨時(shí)訂閱者,例如等待請(qǐng)求響應(yīng)的訂閱者?實(shí)施訂戶重新連接。如果連接中斷或 RabbitMQ 服務(wù)器彈跳,您如何檢測(cè)它并確保重建所有訂閱?了解并實(shí)施服務(wù)質(zhì)量設(shè)置。您需要進(jìn)行哪些設(shè)置以確保您擁有可靠的客戶端。實(shí)施錯(cuò)誤處理策略。如果您的客戶端收到格式錯(cuò)誤的消息,或者拋出意外異常,您應(yīng)該怎么做?實(shí)施發(fā)布者確認(rèn)可靠消息傳遞。EasyNetQ 旨在將所有這些問(wèn)題封裝在一個(gè)簡(jiǎn)單易用的庫(kù)中,該庫(kù)位于現(xiàn)有 AMQP 客戶端之上。它是 RabbitMQ 在大容量商業(yè)環(huán)境中幾年使用經(jīng)驗(yàn)的結(jié)晶。
Part4簡(jiǎn)單使用
接到 RabbitMQ 代理
var bus = RabbitHutch.CreateBus("host=localhost");
發(fā)布消息
await bus.PubSub.PublishAsync(message);
發(fā)布一條延遲5秒的消息
await bus.Scheduler.FuturePublishAsync(message, TimeSpan.FromSeconds(5));
訂閱消息
await bus.PubSub.SubscribeAsync<MyMessage>(
"my_subscription_id", msg => Console.WriteLine(msg.Text)
);
RPC 服務(wù)器
await bus.Rpc.RespondAsync<TestRequestMessage, TestResponseMessage>(request =>
new TestResponseMessage{ Text = request.Text + " all done!" }
);
Part5地址
https://github.com/EasyNetQ/EasyNetQ
