RabbitMQ文檔翻譯一(JAVA).Hello World!

RabbitMQ是一個消息代理:它接受和轉發消息。你可以把它想象成一個郵局:當你把你想寄出的郵件放進一個郵箱裏時,你可以確信郵件的收件人最終會收到郵件。類似的,RabbitMQ是一個郵箱、一個郵局和一個郵遞員。

RabbitMQ與郵局的主要區別在於,它不處理紙張信件,而是接受、存儲和轉發二進制的數據信息塊。

RabbitMQ和消息傳遞通常使用一些行業術語

  • 生產只意味着發送。發送消息的程序是生產者:

    img

  • queue是RabbitMQ中的郵箱的名稱。儘管消息流經RabbitMQ和您的應用程序,但它們只能存儲在隊列中。隊列只受主機的內存和磁盤限制的約束,它本質上是一個大的消息緩衝區。許多生產者可以將消息發送到一個隊列,而許多消費者可以嘗試從一個隊列接收數據。如下是我們表示隊列的方式

    img

  • 消費和接收有着相似的含義。消費者是一個主要等待接收消息的程序:

    img

請注意,生產者、消費者和代理不必駐留在同一主機上;事實上,在大多數應用程序中,它們不必駐留在同一主機上。應用程序也可以既是生產者又是消費者。

“Hello World”

在這部分中,我們將用Java編寫兩個程序:一個是發送單個消息的生產者,另一個是接收消息並將其打印出來的消費者。我們將略過Java API中的一些細節,重點放在這件非常簡單的事情上,以便於快速開始上手。一個“Hello World”消息。

在下圖中,“P”是我們的生產者,“C”是我們的消費者。中間的框是一個隊列,是RabbitMQ持有的供消費者使用的的消息緩衝區。

(P) -> [|||] -> (C)

Java客戶端庫
RabbitMQ有多種協議。本教程使用AMQP 0-9-1,這是一個開放的、通用的消息傳遞協議。RabbitMQ有許多不同語言的客戶機。我們將使用RabbitMQ提供的Java客戶端。

下載客戶端庫及其依賴項(SLF4J API和SLF4J Simple)。將這些文件與教程中的Java文件一起復制到工作目錄中。

請注意,SLF4J Simple對於教程來說已經足夠了,但是您應該在生產中使用完整的日誌庫,比如Logback。

(RabbitMQ Java客戶端也在中央Maven存儲庫中,groupId爲com.rabbitmq,artifactId爲amqp-client.)

現在我們有了Java客戶端及其依賴項,我們可以編寫一些代碼。

發送

(P) -> [|||]

我們將調用我們的消息發佈者(sender)發送和消息使用者(receiver)接收。發佈者將連接到RabbitMQ,發送一條消息,然後退出。
在 Send.java,我們需要導入一些類:

import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;

設置啓動類並命名隊列:

public class Send {
  private final static String QUEUE_NAME = "hello";
  public static void main(String[] argv) throws Exception {
      ...
  }
}

然後我們可以創建到服務器的連接:

ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
     Channel channel = connection.createChannel()) {

}

該連接抽象了socket連接,爲我們負責協議版本協商和認證等工作。在這裏,我們連接到本地機器上的RabbitMQ節點-因此是本地主機。如果我們想連接到另一臺機器上的節點,我們只需在這裏指定它的主機名或IP地址。

接下來,我們創建一個通道,這是大多數完成任務的API所在的位置。注意,我們可以使用try-with-resources語句,因爲連接Connection和通道Channel都實現了java.io.Closeable. 這樣我們就不需要在代碼中顯式地關閉它們。

要發送,我們必須聲明要發送到的隊列;然後我們可以將消息發佈到隊列,所有這些都在try with resources語句中:

channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "Hello World!";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");

聲明隊列是等冪的——只有當它不存在時纔會創建它。消息內容是一個字節數組,因此您可以在那裏對任何您喜歡的內容進行編碼。

這裏是完整的Send.java類.

發送不起作用!

如果這是您第一次使用RabbitMQ,而您沒有看到已發送的消息,那麼您可能會撓頭想知道可能是什麼問題。可能代理啓動時沒有足夠的可用磁盤空間(默認情況下至少需要200 MB的可用空間),因此拒絕接受消息。檢查代理日誌文件以確認並在必要時降低限制。配置文件文檔 將向您展示如何設置磁盤可用空間限制。

接收

這是我們的發佈者。我們的消費者監聽來自RabbitMQ的消息,因此與發佈單個消息的發佈者不同,我們將保持它的運行以監聽消息並將其打印出來。

[|||] -> (C)

代碼(在 Recv.java 中)與Send有幾乎相同的import:

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;

我們將使用額外的DeliveryCallback接口來緩衝服務器推送到我們的消息。
設置與發佈服務器相同;我們打開一個連接和一個通道,並聲明要使用的隊列。注意,這與send發佈消息的隊列是匹配的。

public class Recv {

  private final static String QUEUE_NAME = "hello";

  public static void main(String[] argv) throws Exception {
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();

    channel.queueDeclare(QUEUE_NAME, false, false, false, null);
    System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

  }
}

注意,我們在這裏聲明瞭隊列。可能在生產者之前啓動了消費者,所以在嘗試使用隊列中的消息之前,我們要確保隊列存在。

爲什麼不使用try-with-resource語句自動關閉通道和連接?這樣做,可以讓程序運行,然後關閉所有內容,然後退出!這可能會很不方便,因爲我們希望進程在使用者異步偵聽消息到達時保持活動狀態。

我們將告訴服務器從隊列中向我們傳遞消息。由於它將異步地推送消息,因此我們以對象的形式提供回調,該回調將緩衝消息,直到我們準備好使用它們。這就是DeliverCallback子類所做的。

DeliverCallback deliverCallback = (consumerTag, delivery) -> {
    String message = new String(delivery.getBody(), "UTF-8");
    System.out.println(" [x] Received '" + message + "'");
};
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });

這是完整的Recv.java類

整合

您可以使用類路徑上的RabbitMQ java客戶端編譯這兩個文件:

javac -cp amqp-client-5.7.1.jar Send.java Recv.java

要運行它們,您需要rabbitmq-client.jar以及它對類路徑的依賴關係。在終端中,運行消費者(receiver):

java -cp .:amqp-client-5.7.1.jar:slf4j-api-1.7.26.jar:slf4j-simple-1.7.26.jar Recv

然後,運行生產者(sender):

java -cp .:amqp-client-5.7.1.jar:slf4j-api-1.7.26.jar:slf4j-simple-1.7.26.jar Send

在Windows上,使用分號而不是冒號分隔類路徑中的項。
消費者將通過RabbitMQ打印從生產者處獲得的消息。消費者將繼續運行,等待消息(使用Ctrl-C停止),因此嘗試從另一個終端運行發佈服務器。

列出隊列
您可能希望看到RabbitMQ有哪些隊列以及其中有多少消息。您可以使用rabbitmqctl工具(作爲特權用戶)執行此操作:

sudo rabbitmqctl list_queues

在Windows上,省略sudo:

rabbitmqctl.bat list_queues

是時候進入第2部分並構建一個簡單的工作隊列了。

提示
爲了節省輸入,您可以爲類路徑設置一個環境變量,例如。

export CP=.:amqp-client-5.7.1.jar:slf4j-api-1.7.26.jar:slf4j-simple-1.7.26.jar
java -cp $CP Send

在Windows上:

set CP=.;amqp-client-5.7.1.jar;slf4j-api-1.7.26.jar;slf4j-simple-1.7.26.jar
java -cp %CP% Send
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章