Like Share Discussion Bookmark Smile

J.J. Huang   2019-04-26   Spring Boot   瀏覽次數:

SpringBoot - 第三十七章 | ActiveMQ的集成和使用

SpringBoot - 第二十六章 | RabbitMQ的集成和使用 介紹過RabbitMQ,這章節講解下消息隊列ActiveMQ的集成和簡單使用示例。


ActiveMQ介绍

什麼是Apache ActiveMQ Artemis?

  • Apache ActiveMQ Artemis是一個開源項目,用於構建多協議,可嵌入,高性能,集群的異步消息傳遞系統。

  • Apache ActiveMQ Artemis是面向消息的中間件(MoM)的一個示例。有關MoM和其他消息傳遞概念的說明,請參閱消息傳遞概念

ActiveMQ官方

Queues vs. Topics vs. Virtual Topics (in ActiveMQ)

ActiveMQ提供各種不同的消息傳遞模式。雖然隊列和主題是最著名的,但虛擬主題可以結合兩全其美:多個消費者擁有自己的專用隊列。


Queues

Queues是ActiveMQ實現的最明顯的消息傳遞模式。它們提供了生產者和消費者之間的直接渠道。生產者建立消息,而消費者一個接一個地閱讀。閱讀完郵件後,它就消失了。如果為隊列註冊了多個使用者,則只有其中一個將獲得該消息。

優點

  • 具有透明通信流的簡單消息傳遞模式
  • 可以通過將消息放回隊列來恢復消息

缺點

  • 只有一個消費者可以獲得消息
  • 意味著生產者和消費者之間的耦合,因為它是一對一的關係

Topics

主題在生產者和多個消費者之間實現一對多渠道。與隊列不同,每個消費者都會收到生產者發送的消息。

優點

  • 多個消費者可以收到消息
  • 生產者和消費者之間的脫鉤(發布和訂閱模式)

缺點

  • 更複雜的溝通流程
  • 無法為單個偵聽器恢復消息

Virtual Topics

虛擬主題結合了兩種方法。當生產者向主題發送消息時,消費者將在他們自己的專用隊列上接收消息的副本。

優點

  • 多個消費者可以收到消息
  • 生產者和消費者之間的脫鉤(發布和訂閱模式)
  • 可以通過將消息放回隊列來恢復消息

缺點

  • 可能需要在代理中進行其他配置

結論

隊列和主題都有其自身的缺點。雖然排隊收緊生產者和消費者,但主題缺乏一種簡單的方法來恢復單個消費者的錯誤。虛擬主題為這兩個問題提供了解決方案。生產者和使用者通過發布 - 訂閱模式分離,而錯誤恢復可以在各個隊列上完成。

Docker ActiveMQ準備

1
docker run --name myactivemq -p 61616:61616 -p 8161:8161 -d webcenter/activemq

命令說明:

1
2
3
4
5
- --name myactivemq :將 Container 取名為 myactivemq
- -p 61616:61616 :將 Container 的 61616 Port 映射到主機的 61616 Port
- -p 8161:8161 :將 Container 的 8161 Port 映射到主機的 8161 Port
- -d :後台執行 Container ,並返回ID
- webcenter/activemq :指定安裝的鏡像webcenter/activemq

相關配置

可以通過引入spring-boot-starter-activemq用於支持ActiveMQ。

加入pom的依賴

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>

參數配置

在src/main/resources/application.properties中配置ActiveMQ訊息

1
2
3
4
5
6
# activemq 相關配置
spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.user=admin
spring.activemq.password=admin
spring.activemq.in-memory=true
spring.activemq.pool.enable=false

配置自動加載類為:org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration

建立 ActiveConfig (ActiveMQ的配置類)

注意:這個隊列其實是不需要我們提前定義好的,它和 RabbitMQ 不一樣,它會在我們需要的時候動態的建立。
只需要在Sender和Receiver定義好隊列即可,例:@JmsListener(destination = “J.J.Huang”)、jmsMessagingTemplate.convertAndSend(“J.J.Huang”, msg);

建立 Sender (消息生產者)

通過注入JmsTemplate接口的實例來實現消息的發送。在該生產者,會將接收到的字符串,發送到名為J.J.Huang的隊列中。

建立 Receiver (消息消費者)

通過@JmsListener註解定義該類對J.J.Huang隊列的監聽。該消費者實現了對J.J.Huang隊列的消費,消費操作為輸出消息的字符串內容。

對接測試

在ActiveMQ的控制台,connections -> Connector openwire,可以看見連接對象的。說明已經正常啟動了。

在ActiveMQ的控制台,Queues,可以查看到隊列J.J.Huang的消息。

測試案例

測試(一) 修改 Sender

使用CommandLineRunner,在應用啟動後執行Run,發送1000筆的消息。

測試結果(一)

預期結果為發送的同時也會被消費。

測試(二) 還原 Sender 修改 Chapter37Application

使用@PostConstruct,在應用啟動前,先發送1000筆的消息

測試結果(二)

1
2
3
4
5
6
7
8
9
10
發送消息耗時:2240
收到的 message 是:Hello J.J. Huang, This is message count0
2019-04-25 12:31:16.656 INFO 7761 --- [ main] c.j.l.s.chapter37.Chapter37Application : Started Chapter37Application in 3.532 seconds (JVM running for 3.924)
收到的 message 是:Hello J.J. Huang, This is message count1
收到的 message 是:Hello J.J. Huang, This is message count2
收到的 message 是:Hello J.J. Huang, This is message count3
收到的 message 是:Hello J.J. Huang, This is message count4
收到的 message 是:Hello J.J. Huang, This is message count5
收到的 message 是:Hello J.J. Huang, This is message count6
以下省略...

可以看到發送1000筆消息花費了發送消息耗時:2240,而後續Receiver消費者將消息取下來做處理。

註:以上參考了
Queues vs. Topics vs. Virtual Topics (in ActiveMQ)
(十七)SpringBoot之使用异步消息服务jms之ActiveMQ
SpringBoot ActiveMQ 整合使用
Spring Boot Apache ActiveMq In Memory Example
SpringBoot2.0应用(二):SpringBoot2.0整合ActiveMQ