RabbitMQ英漢互翼(一),RabbitMQ, RabbitMQ教程, RabbitMQ入門

来源:https://www.cnblogs.com/gdsblog/archive/2018/04/11/8796565.html
-Advertisement-
Play Games

RabbitMQ is a message broker: it accepts and forwards messages. You can think about it as a post office: when you put the mail that you want posting i ...


RabbitMQ is a message broker: it accepts and forwards messages. You can think about it as a post office: when you put the mail that you want posting in a post box, you can be sure that Mr. Postman will eventually deliver the mail to your recipient. In this analogy, RabbitMQ is a post box, a post office and a postman.

RabbitMQ 是這樣一個消息代理:它接收和轉發消息。你可以把它想像成是一個郵局:當你把一份郵件投遞到信箱時,你可以確信的是郵遞員先生終究會把郵件遞送給接收者。在這個比喻中,RabbitMQ 扮演了信箱、郵局以及郵遞員這一系列角色。

The major difference between RabbitMQ and the post office is that it doesn't deal with paper, instead it accepts, stores and forwards binary blobs of data ‒ messages.

RabbitMQ與郵局最大的不同在於它並不處理紙質信件,取而代之的是它接收、儲存以及轉發二進位消息數據。

RabbitMQ, and messaging in general, uses some jargon.

RabbitMQ 以及消息傳遞,通常會使用到一些專業術語。

Producing means nothing more than sending. A program that sends messages is a producer :

生產者的含義無非就是發送,一個程式在發送消息時它就是生產者:

Markdown

A queue is the name for a post box which lives inside RabbitMQ. Although messages flow through RabbitMQ and your applications, they can only be stored inside a queue. A queue is only bound by the host's memory & disk limits, it's essentially a large message buffer. Many producers can send messages that go to one queue, and many consumers can try to receive data from one queue. This is how we represent a queue:

隊列實質上就是 RabbitMQ 內部的“信箱”,作為消息,儘管自 RabbitMQ 流經應用程式,但它最終只會存儲於隊列中。隊列只會受限於主機記憶體和磁碟空間,本質上來講它其實是一個龐大的消息緩存區。多個生產者可以發送消息到同一個隊列,同時多個消費者也可以從同一個隊列接收數據。下圖是我們描繪的一個隊列的模樣:

Markdown

Consuming has a similar meaning to receiving. A consumer is a program that mostly waits to receive messages:

同理,消費也有著類似接收的含義,消費者就是一個主要用來等待接收消息的程式:

Markdown

Note that the producer, consumer, and broker do not have to reside on the same host; indeed in most applications they don't.

要註意的是,生產者、消費者,以及代理之間不必存在於同一臺主機,事實上大部分應用程式也不會這麼做。

"Hello World"

"起步"

In this part of the tutorial we'll write two programs in C#; a producer that sends a single message, and a consumer that receives messages and prints them out. We'll gloss over some of the detail in the .NET client API, concentrating on this very simple thing just to get started. It's a "Hello World" of messaging.

在教程的當前部分我們會編寫兩個 C# 程式。作為生產者會發送一條消息,同時消費者會接收消息並將其列印出來。我們會忽略 API 當中的一些細節,把精力集中在簡單的事情上從而更好的起步。這是一個“Hello World”的消息。

In the diagram below, "P" is our producer and "C" is our consumer. The box in the middle is a queue - a message buffer that RabbitMQ keeps on behalf of the consumer.

在下圖中,"P" 就是生產者,"C"就是消費者。中間的方形盒子就是隊列,即 RabbitMQ 為消費者保留的消息緩衝區。

Markdown

The .NET client library

.NET 客戶端庫

RabbitMQ speaks multiple protocols. This tutorial uses AMQP 0-9-1, which is an open, general-purpose protocol for messaging. There are a number of clients for RabbitMQ in many different languages. We'll use the .NET client provided by RabbitMQ.

RabbitMQ 支持多種協議,本教程使用的是 AMQP 0-9-1,它是公開的較為通用的消息協議。RabbitMQ 支持多種語言的客戶端,在這裡我們將使用 RabbitMQ 提供的 .NET 客戶端。

The client supports .NET Core as well as .NET Framework 4.5.1+. This tutorial will use RabbitMQ .NET client 5.0 and .NET Core so you will ensure you have it installed and in your PATH.

RabbitMQ 提供的 .NET 客戶端已支持 .NET Core 以及 .NET Framework 4.5.1+,本教程將會使用 RabbitMQ .NET client 5.0 和 .NET Core,所以你需要確認已安裝成功。

You can also use the .NET Framework to complete this tutorial however the setup steps will be different.

你也可以使用 NET Framework 來完成本教程,然而其安裝步驟會有所不同。

RabbitMQ .NET client 5.0 and later versions are distributed via nuget.

RabbitMQ .NET client 5.0 以及最新的版本是經由 Nuget 來發佈的。

This tutorial assumes you are using powershell on Windows. On MacOS and Linux nearly any shell will work.

本教程假定你在 Windows 操作系統中會使用 PowerShell,可以放心的是,在 MacOS 和 Linux 中幾乎所有的 Shell 環境都能正常運行。

Setup

安裝

First lets verify that you have .NET Core toolchain in PATH:

首先讓我們驗證一下本地環境變數 PATH 中的 .NET Core 工具鏈:

dotnet --help

should produce a help message.

這時應當產生一個幫助消息。

Now let's generate two projects, one for the publisher and one for the consumer:

現在讓我們來創建兩個項目,一個是發佈者,一個是消費者。

dotnet new console --name Send
mv Send/Program.cs Send/Send.cs
dotnet new console --name Receive
mv Receive/Program.cs Receive/Receive.cs

This will create two new directories named Send and Receive.

這一步將會創建兩個文件夾,一個叫 Send,一個叫 Receive。

Then we add the client dependency.

緊接著我們來添加客戶端依賴。

cd Send
dotnet add package RabbitMQ.Client
dotnet restore
cd ../Receive
dotnet add package RabbitMQ.Client
dotnet restore

Now we have the .NET project set up we can write some code.

好了,現在我們完成了 .NET 項目的安裝,這樣就可以寫一些代碼了。

Sending

發送

Markdown

We'll call our message publisher (sender) Send.cs and our message consumer (receiver) Receive.cs. The publisher will connect to RabbitMQ, send a single message, then exit.

隨後我們會調用消息發佈者(發送)Send.cs,以及消息消費者(接收)Receive.cs。發佈者會連接 RabbitMQ,併發送一條消息,然後退出。

In Send.cs, we need to use some namespaces:

在 Send.cs 中,我們需要引入一些命名空間:

using System;
using RabbitMQ.Client;
using System.Text;

Set up the class:

建立類文件:

class Send
{
    public static void Main()
    {
        ...
    }
}

then we can create a connection to the server:

然後我們就可以創建一個通往伺服器的連接。

class Send
{
    public static void Main()
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using (var connection = factory.CreateConnection())
        {
            using (var channel = connection.CreateModel())
            {
                ...
            }
        }
    }
}

The connection abstracts the socket connection, and takes care of protocol version negotiation and authentication and so on for us. Here we connect to a broker on the local machine - hence the localhost. If we wanted to connect to a broker on a different machine we'd simply specify its name or IP address here.

該連接是抽象自套接字連接,為我們處理協議關於版本在協商與認證等方面的事宜。在這裡,我們會連接到本地機器的一個代理,也就是 localhost。如果我們想連接到一臺不同機器上的代理,只需簡單地指定主機名或者 IP 地址。

Next we create a channel, which is where most of the API for getting things done resides.

接下來我們將創建一個通道,它在眾多的 API 中負責著事項的正確處理。

To send, we must declare a queue for us to send to; then we can publish a message to the queue:

為了能順利的發送,我們需要先定義一個隊列,然後我們就可以發佈消息了。

using System;
using RabbitMQ.Client;
using System.Text;

class Send
{
    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);

            string message = "Hello World!";
            var body = Encoding.UTF8.GetBytes(message);

            channel.BasicPublish(exchange: "",
                                 routingKey: "hello",
                                 basicProperties: null,
                                 body: body);
            Console.WriteLine(" [x] Sent {0}", message);
        }

        Console.WriteLine(" Press [enter] to exit.");
        Console.ReadLine();
    }
}

Declaring a queue is idempotent - it will only be created if it doesn't exist already. The message content is a byte array, so you can encode whatever you like there.

聲明隊列的行為是冪等性的 - 即只有當一個隊列不存在時才能被創建。

When the code above finishes running, the channel and the connection will be disposed.

當上述代碼完成時,通道和連接將會被釋放。

Here's the whole Send.cs class.

這裡是完整的 Send.cs 類文件。

Sending doesn't work!
發送運行失敗

If this is your first time using RabbitMQ and you don't see the "Sent" message then you may be left scratching your head wondering what could be wrong. Maybe the broker was started without enough free disk space (by default it needs at least 50 MB free) and is therefore refusing to accept messages. Check the broker logfile to confirm and reduce the limit if necessary. The configuration file documentation will show you how to set disk_free_limit.

如果這是你第一次使用 RabbitMQ,並且你沒有收到“Sent”這一消息,這時你可能會抓耳撓腮,想知道是什麼導致了錯誤。在這種情況下,有很大可能是因為代理(broker)在啟動時沒有足夠的可用磁碟空間(預設至少需要 50M ),因此拒絕接收消息。檢查代理(broker)日誌文件(logfile),併進行確認以減少限制,通過查看配置文件文檔,可以知曉如何設置 disk_free_limit。

Receiving

接收

That's it for our publisher. Our consumer is pushed messages from RabbitMQ, so unlike the publisher which publishes a single message, we'll keep it running to listen for messages and print them out.

以上是我們的發佈者。我們的消費者已開始從 RabbitMQ 上被推送了消息,與發送一條消息的發佈者有所不同的是,我們會讓消費者持續地監聽消息並將其列印出來。

Markdown

The code (in Receive.cs) has almost the same using statements as Send:

在 Receive.cs 類文件中,using 區域的聲明代碼與 Send.cs 類文件近乎相同:

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;

Setting up is the same as the publisher; we open a connection and a channel, and declare the queue from which we're going to consume. Note this matches up with the queue that send publishes to.

與發佈者的設置一樣,我們打開一個連接和通道,並且聲明好隊列以作好消費的準備。需要註意的是,該隊列與發佈者所發送消息的隊列是相匹配的(即基於同一個隊列)。

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);
                ...
            }
        }
    }
}

Note that we declare the queue here, as well. Because we might start the consumer before the publisher, we want to make sure the queue exists before we try to consume messages from it.

可以看到我們在消費者這裡又聲明瞭一次隊列(QueueDeclare),在實踐中,我們很可能是先啟動消費者,後啟動發佈者。所以重覆的聲明代碼,是當我們嘗試從隊列中消費消息時,確保隊列總是已存在的。

We're about to tell the server to deliver us the messages from the queue. Since it will push us messages asynchronously, we provide a callback. That is what EventingBasicConsumer.Received event handler does.

我們即將告知伺服器從隊列中向我們遞送消息,因為該動作是基於非同步的,所以我們需要提供回調,這便是 EventingBasicConsumer.Received 事件處理方法所要做的。

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;

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);

            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body);
                Console.WriteLine(" [x] Received {0}", message);
            };
            channel.BasicConsume(queue: "hello",
                                 autoAck: true,
                                 consumer: consumer);

            Console.WriteLine(" Press [enter] to exit.");
            Console.ReadLine();
        }
    }
}

Here's the whole Receive.cs class.

這裡是完整的 Receive.cs 類文件

Putting It All Together

融合一起

Open two terminals.

打開兩個終端。

Run the consumer:

運行消費者:

cd Receive
dotnet run

Then run the producer:

緊接著運行生產者:

cd Send
dotnet run

The consumer will print the message it gets from the publisher via RabbitMQ. The consumer will keep running, waiting for messages (Use Ctrl-C to stop it), so try running the publisher from another terminal.

消費者會經由 RabbitMQ 列印出那些來自發佈者的消息。消費者會持續運行,以等待消息(使用 Ctrl-C 來終止運行),如此,我們可以嘗試從其他終端來運行發佈者(重覆運行多個生產者實常式序)。


 【轉:http://www.cnblogs.com/ramantic/p/7993047.html

歡迎大家關註我都我的微信 公眾號,公眾號漲粉絲人數,就是你們對我的喜愛程度!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.Slice(切片)代表變長的序列,序列中每個元素都有相同的類型,一個slice類型一般寫作[]T,其中T代表slice中元素的類型;slice的語法和數組很像,只是沒有固定長度而已,slice的底層確實引用一個數組對象 2.內置的len和cap函數分別返回slice的長度和容量 3.s[i:j] ...
  • Java 內部類分為: 1)成員內部類 2)靜態嵌套類 3)方法內部類 4)匿名內部類 內部類的共性 1、內部類仍然是一個獨立的類,在編譯之後內部類會被編譯成獨立的.class文件,但是前面冠以外部類的類名和$符號 。 2、內部類不能用普通的方式訪問。內部類是外部類的一個成員,因此內部類可以自由地訪 ...
  • 方法 綁定方法和非綁定方法 綁定方法和非綁定方法在創建時沒有任何區別,同一方法,既可以為綁定方法,也可以為非綁定方法,一切不同都只在調用時的手法上有所區別。 綁定方法即該方法綁定類的一個實例上,必須將self作為第一個參數傳入,而這個過程是由Python自動完成。可以通過實例名.方法名(參數列表)來 ...
  • 出現這個問題的原因可能很多,但是最終原因都是部署的項目文件中沒有這個類包。 那麼出錯的點在哪呢?逐一排除! 1.首先在項目文件中沒有添加相應的jar包,可以在maven dependencis文件夾中看是否有。如果沒有,在pom文件添加依賴配置即可;如果有,還是出現問題轉第二步 2.在maven的本 ...
  • 概述 UWP Community Toolkit Extensions 中有一個為 View 提供的擴展 - View Extensions,本篇我們結合代碼詳細講解 View Extensions 的實現。 View Extensions 包括了 ApplicationViewExtensions ...
  • 文章是很基礎,但很實用,看了這篇文章,讓我一下回到了2016年剛剛學委托的時候,故轉之! 1.委托 委托類似於C++中的函數指針(一個指向記憶體位置的指針)。委托是C#中類型安全的,可以訂閱一個或多個具有相同簽名方法的函數指針。簡單理解,委托是一種可以把函數當做參數傳遞的類型。很多情況下,某個函數需要 ...
  • •LINQ(發音:Link)是語言級集成查詢(Language INtegrated Query) •LINQ是一種用來進行數據訪問的編程模型,使得.NET語言可以直接支持數據查詢 •LINQ的目標是降低訪問數據的複雜度 •LINQ可以用統一的方法訪問不同類型的數據,可以將數據作為對象使用 •能夠更 ...
  • 寫過介面的同學都知道,介面會越來越多,那麼控制器也會越來越多。這時候就需要根據某種業務或特性對controller進行分類然後建立文件夾。 我想到一個折中的方案:偽Areas! 在Areas文件夾下建立對應的文件夾,比如說用戶相關的,建立一個Account文件夾 圖中就是我創建的文件夾及對應的Con ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...