目錄
簡介
服務之間的同步調用,可以使用 HTTP 或 RPC 來完成,但并非所有的調用都需要同步,有些場景下,當客戶端調用服務端時,并不需要等待服務端做出響應,此時就應該使用異步調用。異步調用的常用方式是基于 MQ (Message Queue) 來實現的。下文會以 ActiveMQ 為例進行講解。
ActiveMQ 是 Java 世界中最為流行的開源消息中間件,它不僅功能強大,而且性能穩定。它可全面支持 JMS(Java 消息服務)技術規范,為 Java 應用程序提供標準的 JMS API。
此外 ActiveMQ 具備與 Spring 框架整合的能力,它一直都是 Spring 應用程序的消息中間件標配。同樣, Spring Boot 也提供了 ActiveMQ 的開箱即用的插件,只需要幾項配置,就能接入 ActiveMQ,并輕松使用 JMS API 編寫異步消息通信程序。
Active MQ 官網地址如下
http://activemq.apache.org
啟動 ActiveMQ 服務器
先使用 docker 安裝 ActiveMQ ,目前 ActiveMQ 官方并未提供相應的 Docker 鏡像,我們選擇使用第三方鏡像 webcenter/activemq 。
docker pull webcenter/activemq:5.14.3
接下來運行 ActiveMQ
docker run -d -p 8161:8161 -p 61616:61616 -e ACTIVEMQ_ADMIN_LOGIN=admin -e ACTIVEMQ_ADMIN_PASSWORD=admin --name activemq webcenter/activemq:5.14.3
在啟動 ActiveMQ 容器時,容器對宿主機暴露了兩個端口號:
8161: 表示 ActiveMQ 控制臺端口號,可在瀏覽器中通過控制臺來執行 ActiveMQ 的相關操作
61616: 表示 ActiveMQ 所監聽的 TCP 端口號,應用程序可通過該端口號與 ActiveMQ 建立 TCP 連接,并完成后續的異步消息通信
此外,在啟動 ActiveMQ 容器時,還提供了兩個環境變量
ACTIVEMQ_ADMIN_LOGIN: 用于設置控制臺管理員的用戶名,默認為 admin
ACTIVEMQ_ADMIN_PASSWORD: 用于設置控制臺管理員的密碼,默認為 admin
查看控制臺
webcenter/activemq 鏡像擁有一個基于 Web 的控制臺,可通過瀏覽器訪問。容器啟動完畢后,可以打開瀏覽器,并在地址欄中輸入 http://localhost:8161
點擊 Manage ActiveMQ borker 鏈接,瀏覽器將彈出一個對話框,此時輸入用戶名和密碼,認證通過后會進入管理界面
在管理界面中,包括 8 個功能菜單
Home: 基本信息
Queues: 管理的隊列
Topics: 查看所管理的主題
Subscribers: 查看相關主題的訂閱者
Connections: 查看客戶端的連接信息
Network: 查看網絡相關信息
Scheduled: 查看 ActiveMQ 內部運行的定時任務
Send: 通過表單方式查看向隊列或主題發送具體消息
ActiveMQ 的消息通道
ActiveMQ 管理了兩類消息通道,一類是隊列(Queue),另一類叫做主題(Topic)。
Queue
Queue 用于解決消息的 點對點 通信問題,也就是說,消息從生產者(Producer) 發出后,首先進入 ActiveMQ 某個指定的 Queue 中,然后再將消息傳送給其中一個消費者(Consumer)。
Topic
Topic 用于解決消息的發布與訂閱(Publish-subscribe) 通信問題,也就是說,消息從 Producer 發出后,首先將其發布到 ActiveMQ 某個指定的 Topic 上,然后將此消息分發給每個訂閱者(Subscriber) 。
比較
在具體場合下,靈活使用以上兩種通信模式來實現 Producer 與 Consumer/Subscriber 間的異步調用,從而解決調用方的耦合問題。可見,Queue 能解決調用緩沖問題,Topic 能解決消息廣播問題, Queue 與 Topic 都能解決掉調用耦合問題,這些技術都為一個好的軟件架構提供了有效的支撐。
開發生產者和消費者
下面就以 Queue 為例,將 ActiveMQ 與 Spring Boot 進行整合,將 Producer 作為客戶端, Consumer 作為服務端,通過 Queue 實現客戶端與服務端的異步調用
開發服務端(消費者)
首先創建一個名為 acitvemq-hello-server 的 spring boot 項目,如果在 eclipse 中安裝了 Spring Tools ,可以在新建時選擇 New Spring Starter Project 選項。或者新建 Maven 工程。對應的 maven 依賴如下
org.springframework.boot
spring-boot-starter-parent
1.5.19.RELEASE
org.springframework.boot
spring-boot-starter-activemq
在 Spring Boot 框架中已經內置了對 ActiveMQ 的支持,我們只需要依賴 spring-boot-starter-mq 就能啟動 ActiveMQ,此時還需要在 application.properties 文件中添加 ActiveMQ 配置項
spring.activemq.broker-url=tcp://10.104.10.1:61616
spring.activemq.user=admin
spring.activemq.password=admin
接下來創建 HelloServer 的類,封裝服務端相關代碼
@Component
public class HelloServer {
@JmsListener(destination="hello-queue")
public void receive(String message) {
System.out.println(message);
}
}
使用 @Component 注解,說明它可被 Spring IoC 容器所管理。此時只需要使用 @JmsListener 注解,并將其綁定到 receive() 方法上,就能從 ActiveMQ 中接收響應的消息。
@JmsListener 注解中需要添加一個 destination 屬性來指定 Queue/Topic 的名稱,該名稱具有唯一性。消息將以一個 String 類型參數的形式傳入方法體中,也可以接收其他類型的消息,這取決于客戶端發送的消息是哪種類型。Spring JMS 將消息放入 ActiveMQ 時會進行序列化,當消息從 ActiveMQ 取出時將進行反序列化,應用程序無需關注這些底層細節,只需要將精力放在業務邏輯上。
最后,編寫一個 Spring Boot 應用程序啟動類來啟動服務端(使用 spring tools 工具會自動生成)
@SpringBootApplication
public class ActivemqHelloServerApplication {
public static void main(String[] args) {
SpringApplication.run(ActivemqHelloServerApplication.class, args);
}
}
當服務端啟動完畢后,將一直監聽 ActiveMQ 的 hello-queue 隊列中即將到來的消息,消息由客戶端來發送。
開發客戶端(生產者)
創建一個名為 active-mq-client 的 Maven 項目, pom.xml 文件內容與服務端相似。application.properties 文件與服務端相同。
接下來創建一個名為 HelloClient 的類,將其作為客戶端。
@Component
public class HelloClient {
@Autowired
private JmsTemplate jmsTemplate;
public void send(String message) {
jmsTemplate.convertAndSend("hello-queue", message);
}
}
這里使用了 @Autowired 注解, JmsTemplate 對象注入進來,還編寫了一個 send() 方法,在該方法中調用 JmsTemplate 對象的 convertAndSend 來轉換并發送消息。
最后使用 Spring Boot 應用程序啟動類來啟動客戶端
@SpringBootApplication
public class ActivemqHelloClientApplication {
@Autowired
private HelloClient helloClient;
@PostConstruct
public void init() {
helloClient.send("hello world");
}
public static void main(String[] args) {
SpringApplication.run(ActivemqHelloClientApplication.class, args);
}
}
需要注意的是, init() 方法帶有 @PostConstruct 注解,表示 Spring IoC 容器實例化 ActivemqHelloClientApplication 類后將調用該方法。
運行 main() 方法可以啟動客戶端應用程序,并可以在服務端應用程序控制臺中看到 client 發送的消息,也可以在 ActiveMQ 控制臺中查看隊列的當前狀態
Queue 表格中列明的含義如下
Name 表示隊列名稱,可在應用程序中自動創建,也可在 ActiveMQ 控制臺中手動創建
Number Of Pending Messages 表示阻塞在隊列中未經消費的消息條數
Number Of Consumers 表示正在與 ActiveMQ 建立連接的消費者數量
Messages Enqueued 表示進入隊列的消息數量
Messages Dequeued 表示離開隊列的消息數量
此外,還有下面幾種操作
Browser 用于查看當前隊列中消息的相關細節
Active Consumers 用于查看當前活動消費者的相關信息
Active Producers 用于查看當前活動生產者的相關信息
Send To 用于向當前隊列中發送具體消息
Purge 用于清空隊列中的消息
Delete 用于刪除當前隊列
參考
《架構探險—輕量級微服務架構》
原文:https://www.cnblogs.com/reycg-blog/p/10265139.html