使用Spring AMQP進行消息傳遞

使用Spring AMQP進行消息傳遞

本文討論使用Spring AMQP框架實現AMQP消息通信。先介紹一些消息通信核心概念,然後通過一個實際示例進行實戰。

1. 核心概念

1.1. 消息傳輸

消息傳輸是應用間進行消息通信的技術,基於異步消息傳輸代替基於請求-響應的同步架構。消息的生產者和消費者被中介消息層(也稱爲消息代理)解耦。消息代理具有消息持久化、消息過濾以及消息轉換等特性。

消息傳遞鍵間的應用都是Java語言實現,則通常使用 JMS (Java Message Service) API。對於不同平臺和提供商之間相互通信不能使用JMS客戶端和代理服務器,這時需要使用AMQP。

1.2. AMQP – Advanced Message Queuing Protocol

AMQP是實現異步消息通信的開放標準連接規範,提供了應該如何構造消息的描述。

與JMS的差異

AMQP是平臺獨立二進制協議標準,庫可以使用不同語言實現並運行與不同環境中。不受限與特定廠商,因此可以實現JMS代理之間遷移,主流的AMQP消息代理是 RabbitMQ, OpenAMQ, StormMQ。

AMQP實體

簡要理解,AMQP有Exchange, Queue, Binding組成:
在這裏插入圖片描述
Exchange類似於郵電局或郵箱,客戶端發佈消息至AMQP exchange,有四種內置交換類型:

直接交換(Direct Exchange):通過完全匹配路由key路由消息至特定的隊列。
扇出交換(Fanout Exchange): 路由消息至所有綁定的隊列。
主題交換(Topic Exchange):路由消息至匹配特定模式的路由key的多個隊列。
頭信息交換(Headers Exchange): 基於消息頭路由消息。

Queue 使用路由key綁定exchange。

Message 消息使用路由key發送至exchange,然後exchange分發消息副本至各個隊列。

Spring AMQP

Spring AMQP有兩個模塊組成:spring-amqp 和 spring-rabbit,這些模塊提供下列內容的抽象:

AMQP 實體 – 使用Message, Queue, Binding, Exchange 類創建AMQP 實體。
連接管理 – 使用CachingConnectionFactory連接至 RabbitMQ 代理。
消息發佈 – 使用RabbitTemplate發送消息。
消息消費 – 使用 @RabbitListener 註解從隊列讀消息。

2. 創建Spring Amqp 示例應用

2.1. 安裝 AMQP 消息代理

首先需要連接到RabbitMQ消息代理服務,最簡單的方法是使用Docker獲取並運行RabbitMQ:

docker run -d -p 5672:5672 -p 15672:15672 --name my-rabbit rabbitmq:3-management

我們暴露5672端口爲了讓我們應用可以連接RabbitMQ。同時暴露15672爲了通過管理界面看RabbitMQ正在做什麼,url爲:http://localhost:15672 ,HTTP API: http://localhost:15672/api/index.html。

現在我們通過Spring AMQP創建應用發送和接收"hello world"消息.

2.2. MAVEN依賴

爲了增加spring-amqp 和 spring-rabbit 模塊,需增加boot-starter-amqp 依賴:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
        <version>2.1.6.RELEASE</version>
    </dependency>
</dependencies>

讀者可以適合的版本。

2.3. 連接至RabbitMQ代理服務器

使用Spring Boot 自動配置創建了 ConnectionFactory, RabbitTemplate, RabbitAdmin bean。因此我們有至RabbitMQ的連接在5672,並使用缺省的用戶和密碼:guest。我們僅需要災厄應用使用 @SpringBootApplication註解:

@SpringBootApplication
public class HelloWorldMessageApp {
   // ...
}

2.4. 創建隊列

通過簡單定義Queue類型bean即可創建隊列。RabbitAdmin會發現並使用路由key(myQueue)綁定至缺省exchange:

@Bean
public Queue myQueue() {
    return new Queue("myQueue", false);
}

如果需要定義多個隊列,使用不同的方法名,則默認Bean名稱與方法名一致。

@Bean
Queue queue1() {
    return new Queue(“queue1”, false);
}

@Bean
Queue queue2() {
    return new Queue(“queue2”, false); 
}

我們將隊列設置爲非持久性,即當RabbitMQ停止時隊列中的任何消息將會刪除。但重啓我們應用程序對隊列沒有影響。
如果需要重啓消息代理服務器隊列仍然存在,需要通過參數true設置隊列爲持久狀態,但不能保證其中的消息仍然存在,如果必要需設置消息投遞模式爲持久化模式。

2.5. 發送消息

使用RabbitTemplate 發送 “Hello, world!”:

rabbitTemplate.convertAndSend("myQueue", "Hello, world!");

2.6. 消費消息

通過@RabbitListener註解實現消費消息:

@RabbitListener(queues = "myQueue")
public void listen(String in) {
    System.out.println("Message read from myQueue : " + in);
}

2.7. 運行示例

首先啓動RabbitMQ代理:

docker run -d -p 5672:5672 -p 15672:15672 --name my-rabbit rabbitmq:3-management

然後運行spring boot應用,HelloWorldMessage.java中的main方法:

mvn spring-boot:run -Dstart-class=com.baeldung.springamqp.simple.HelloWorldMessageApp

當應用正運行時我們會看到:

  • 應用發送消息至缺省exchange,使用myQueue作爲路由key
  • 然後隊列myQueue接收到消息
  • 最後監聽方法從隊列myQueue中消費消息,然後打印至控制檯

我們也可以使用RabbitMQ管理url http://localhost:15672 查看發送的消息和消費的消息。

3. 總結

本文我們介紹使用Spring AMQP實現AMQP規範的消息通信應用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章