一、簡介
RabbitMQ是一個消息的代理器,用於接收和發送消息,你可以這樣想,他就是一個郵局,當您把需要寄送的郵件投遞到郵筒之時,你可以確定的是郵遞員先生肯定會把郵件發送到需要接收郵件的人的手里,不會送錯的。在這個比喻中,RabbitMQ就是一個郵箱,也可以理解為郵局和郵遞員,他們負責把消息發送出去和用於接收信息。
RabbitMQ和郵局這兩者之間的主要區別是它不會處理紙質郵件,取而代之的是接收、存儲和發送二進制數據塊,也就是我們通常所說的消息。
RabbitMQ和消息中,通常會使用一些專業術語。
生產:生產意味着就是發送。 發送消息的程序是一個生產者。下圖代表一個消息的生產真:
隊列:這里的隊列是指一個名稱,但是名稱所代表的隊列實體寄存在RabbitMQ服務器端中。 雖然消息流過RabbitMQ和您的應用程序,但它們只能存儲在隊列中。 隊列只受主機的內存和磁盤的限制,它本質上是一個大的消息緩沖區。 許多生產者可以發送消息到一個隊列,許多消費者可以嘗試從一個隊列接收數據。 下圖代表一個隊列:
消費:消費具有與接收相似的含義。 消費者是一個主要等待接收消息的程序。下圖代表消息的消費者:
二、(使用 Net/C# 客戶端)
在這篇教程中我們將用C#寫兩個程序;一個是生產者,用於發送一個簡單消息;一個是消費者,用於接收消息和把他們打印出來。我們將忽略一些.NET API的詳細信息,專注於更簡單的開始。這是一個關於"Hello World"簡單的小例子。
在下圖中, "P"是我們的消息生產者,"C"是我們消息的消費者。在中間的紅色矩形框代表一個隊列,也就是消息的緩沖區,RabbitMQ代表是消息的消費者。
![(P) -> [|||] -> (C)](/image/aHR0cDovL3d3dy5yYWJiaXRtcS5jb20vaW1nL3R1dG9yaWFscy9weXRob24tb25lLnBuZw==.png)
Net客戶端類庫
RabbitMQ支持多種協議,本教程使用AMQP 0-9-1,這是一個針對消息的開放的、通用的協議。RabbitMQ使用了多種語言開發了針對不同環境的客戶端。下面我們將使用由RabbitMQ提供的Net客戶端。
這個客戶端類庫支持.NET Core以及.NET Framework 4.5.1 以上的版本。本教程將使用.NET Core,以便確保您安裝在您的路徑中。
你也可以使用 Net Framework 來完成本實例,只是安裝步驟有些不同而已。
RabbitMQ的客戶端類庫已經部署到了NuGet上,並且您可以通過NuGet下載和使用。
本教程假定您正在使用Windows PowerShell。
三、安裝
首先讓我們確認您已經有了Net Core 的工具鏈在路徑中:
dotnet --help
應該生成一個幫助消息。
現在讓我們生成兩個項目,一個是生產者的項目,一個是消費者的項目
dotnet new console --name Send mv Send/Program.cs Send/Send.cs dotnet new console --name Receive mv Receive/Program.cs Receive/Receive.cs
這將生成兩個目錄,一個目錄是Send,另一個目錄是Receive.
然后我們增加客戶端的依賴
cd Send dotnet add package RabbitMQ.Client dotnet restore cd ../Receive dotnet add package RabbitMQ.Client dotnet restore
現在我們已經有了兩個項目安裝完畢,可以開始寫一些代碼了。
四、發送消息
我們會調用我們的消息發布者(發送者)send.cs和消息消費者(接受者)receive.cs。發送者鏈接到RabbitMQ,並且發送一個單一消息,然后退出。
在Send.cs文件中,我們需要引入一些命名空間:
using System; using RabbitMQ.Client; using System.Text;
設置類:
class Send { public static void Main() { ... } }
然后我們創建一個連接,連接到服務器:
class Send { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { ... } } } }
當前connection連接是一個抽象的套接字連接,為我們負責協議版本的協商和認證等。這里我們連接到本地機器上的消息代理--從此處的localhost關鍵字可以看出是本機。如果我們想連接到另一台機器上的一個消息代理,我們只需在這里指定它的名稱或IP地址。
接下來,我們創建一個通道,這個API的主要功能就是把獲得信息保存起來
要發送,我們必須聲明一個隊列,然后我們把消息發送到這個隊列里面:
1 using System; 2 using RabbitMQ.Client; 3 using System.Text; 4 5 class Send 6 { 7 public static void Main() 8 { 9 var factory = new ConnectionFactory() { HostName = "localhost" }; 10 using(var connection = factory.CreateConnection()) 11 using(var channel = connection.CreateModel()) 12 { 13 channel.QueueDeclare(queue: "hello", 14 durable: false, 15 exclusive: false, 16 autoDelete: false, 17 arguments: null); 18 19 string message = "Hello World!"; 20 var body = Encoding.UTF8.GetBytes(message); 21 22 channel.BasicPublish(exchange: "", 23 routingKey: "hello", 24 basicProperties: null, 25 body: body); 26 Console.WriteLine(" [x] Sent {0}", message); 27 } 28 29 Console.WriteLine(" Press [enter] to exit."); 30 Console.ReadLine(); 31 } 32 }
聲明隊列是一次性的,只有當它不存在時才會被創建。消息內容是字節數組,所以您可以編碼任何您喜歡的內容。
當上面的代碼完成運行時,通道和連接將被釋放。
發送不成功的解決辦法
如果這是您第一次使用RabbitMQ發送消息,但是你並沒有看到“發送”的消息,那么你可能會撓着頭想知道錯誤在什么地方。也許消息代理開始沒有足夠的可用磁盤空間(默認情況下,它需要至少50 MB),因此拒絕接受消息。必要時檢查代理日志文件來確認和減少限制。配置文件的文檔會告訴你如何設置disk_free_limit。
五、接收消息
以上就是我們的消息生產者,我們的消息的消費者是從RabbitMQ拉消息,因此不能像我們的消息發布者那樣發布單一消息,我們需要保持我們的消費者程序持續運行,並且監聽消息,如果有就獲取並且打印出來。
![[|||] -> (C)](/image/aHR0cDovL3d3dy5yYWJiaXRtcS5jb20vaW1nL3R1dG9yaWFscy9yZWNlaXZpbmcucG5n.png)
Receive.cs文件和Send.cs文件有一些很像的代碼需要書寫:
using RabbitMQ.Client; using RabbitMQ.Client.Events; using System; using System.Text;
消息接收者的設置和消息的發布者一樣,我們要打開一個連接和一個通道,並且聲明一個從中獲取消息的隊列,注意這個是和Send.cs文件中的發布者的隊列相匹配的。
class Receive { public static void Main() { var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null); ... } } } }
注意,我們也在這里聲明隊列。因為我們可能在發行者之前啟動消費者,所以我們要確保隊列在我們嘗試從它中獲取消息之前存在。
我們正要告訴服務器從隊列中傳遞消息。因為它會異步推送我們的消息,我們提供了一個回調。那是EventingBasicConsumer接收事件處理程序所做的。
1 using RabbitMQ.Client; 2 using RabbitMQ.Client.Events; 3 using System; 4 using System.Text; 5 6 class Receive 7 { 8 public static void Main() 9 { 10 var factory = new ConnectionFactory() { HostName = "localhost" }; 11 using(var connection = factory.CreateConnection()) 12 using(var channel = connection.CreateModel()) 13 { 14 channel.QueueDeclare(queue: "hello", 15 durable: false, 16 exclusive: false, 17 autoDelete: false, 18 arguments: null); 19 20 var consumer = new EventingBasicConsumer(channel); 21 consumer.Received += (model, ea) => 22 { 23 var body = ea.Body; 24 var message = Encoding.UTF8.GetString(body); 25 Console.WriteLine(" [x] Received {0}", message); 26 }; 27 channel.BasicConsume(queue: "hello", noAck: true, consumer: consumer); 28 29 Console.WriteLine(" Press [enter] to exit."); 30 Console.ReadLine(); 31 } 32 } 33 }
六、把它放在一起
打開兩個端點。
運行消費者:
cd Receive
dotnet run
然后運行生產者
cd Send
dotnet Run
消費者將要打印消息生產者通過RabbitMQ發布的消息。消費者不能間斷,必須保持持續運行,等待新消息的到來。當然也可以通過(Ctrl+C 來停止消費者)
好了,終於寫完了,其實是我翻譯的,有翻譯不對的地方請諒解。
原文地址如下:http://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html