在 Spring 生态中玩轉 RocketMQ 系列教程現已登陸知行動手實驗室,
點選這裡立即體驗!
移動端同學,需要在PC端登入 start.aliyun.com 進行體驗。
RocketMQ 作為業務消息的首選,在消息和流處理領域被廣泛應用。而微服務生态 Spring 架構也是業務開發中最受歡迎的架構,兩者的完美契合使得 RocketMQ 成為 Spring Messaging 實作中最受歡迎的消息實作。本文展示了 5 種在 Spring 生态中文玩轉 RocketMQ 的方式,并描述了每個項目的特點和使用場景。
一、前言
上世紀 90 年代末,随着 Java EE(Enterprise Edition)的出現,特别是 Enterprise Java Beans 的使用需要複雜的描述符配置和死闆複雜的代碼實作,增加了廣大開發者的學習曲線和開發成本,由此基于簡單的 XML 配置和普通 Java 對象(Plain Old Java Objects)的 Spring 技術應運而生,依賴注入(Dependency Injection),控制反轉(Inversion of Control)和面向切面程式設計(AOP)的技術更加靈活地解決了傳統 Java 企業及版本的不足。随着 Spring 的持續演進,基于注解(Annotation)的配置逐漸取代了 XML 檔案配置。除了依賴注入、控制翻轉、AOP 這些技術,Spring 後續衍生出 AMQP、Transactional、Security、Batch、Data Access 等子產品,涉及開發的各個領域。
2014 年 4 月 1 日,Spring Boot 1.0.0 正式釋出。它基于“約定大于配置”(Convention over configuration)這一理念來快速地開發,測試,運作和部署 Spring 應用,并能通過簡單地與各種啟動器(如spring-boot-web-starter)結合,讓應用直接以指令行的方式運作,不需再部署到獨立容器中。Spring Boot 的出現可以說是 Spring 架構的第二春,它不但簡化了開發的流程,目前更是事實标準。下面這幅圖可以看出相同功能的 Spring 和 Spring Boot 的代碼實作對比。
Apache RocketMQ 是一款是業界知名的分布式消息和流進行中間件,它主要功能是消息分發、異步解耦、削峰填谷等。RocketMQ 是一款金融級消息及流資料平台,RocketMQ 在交易、支付鍊路上用的很多,主要是對消息鍊路品質要求非常高的場景,能夠支援萬億級消息洪峰。RocketMQ 在業務消息中被廣泛應用,并衍生出順序消息、事務消息、延遲消息等比對各類業務場景的特殊消息。
本文的主角就是 Spring 和 RocketMQ,那幾乎每個 Java 程式員都會使用 Spring 架構與支援豐富業務場景的 RocketMQ 會碰撞出怎麼樣的火花?
二、RocketMQ 與 Spring 的碰撞
在介紹 RocketMQ 與 Spring 故事之前,不得不提到 Spring 中的兩個關于消息的架構,Spring Messaging 和 Spring Cloud Stream。它們都能夠與 Spring Boot 整合并提供了一些參考的實作。和所有的實作架構一樣,消息架構的目的是實作輕量級的消息驅動的微服務,可以有效地簡化開發人員對消息中間件的使用複雜度,讓系統開發人員可以有更多的精力關注于核心業務邏輯的處理。
1. Spring Messaging
Spring Messaging 是 Spring Framework 4 中添加的子產品,是 Spring 與消息系統內建的一個擴充性的支援。它實作了從基于 JmsTemplate 的簡單的使用 JMS 接口到異步接收消息的一整套完整的基礎架構,Spring AMQP 提供了該協定所要求的類似的功能集。在與 Spring Boot 的內建後,它擁有了自動配置能力,能夠在測試和運作時與相應的消息傳遞系統進行內建。單純對于用戶端而言,Spring Messaging 提供了一套抽象的 API 或者說是約定的标準,對消息發送端和消息接收端的模式進行規定,比如消息 Messaging 對應的模型就包括一個消息體 Payload 和消息頭 Header。不同的消息中間件提供商可以在這個模式下提供自己的 Spring 實作:在消息發送端需要實作的是一個 XXXTemplate 形式的 Java Bean,結合 Spring Boot 的自動化配置選項提供多個不同的發送消息方法;在消息的消費端是一個 XXXMessageListener 接口(實作方式通常會使用一個注解來聲明一個消息驅動的 POJO),提供回調方法來監聽和消費消息,這個接口同樣可以使用 Spring Boot 的自動化選項和一些定制化的屬性。
在 Apache RocketMQ 生态中,RocketMQ-Spring-Boot-Starter(下文簡稱 RocketMQ-Spring)就是一個支援 Spring Messaging API 标準的項目。該項目把 RocketMQ 的用戶端使用 Spring Boot 的方式進行了封裝,可以讓使用者通過簡單的 annotation 和标準的 Spring Messaging API 編寫代碼來進行消息的發送和消費,也支援擴充出 RocketMQ 原生 API 來支援更加豐富的消息類型。在 RocketMQ-Spring 畢業初期,RocketMQ 社群同學請 Spring 社群的同學對 RocketMQ-Spring 代碼進行 review,引出一段羅美琪(RocketMQ)和春波特(Spring Boot)故事的佳話[1],著名 Spring 布道師 Josh Long 向國外同學介紹如何使用 RocketMQ-Spring 收發消息[2]。RocketMQ-Spring 也在短短兩年時間超越 Spring-Kafka 和 Spring-AMQP(注:兩者均由 Spring 社群維護),成為 Spring Messaging 生态中最活躍的消息項目。
2. Spring Cloud Stream
Spring Cloud Stream 結合了 Spring Integration 的注解和功能,它的應用模型如下:
Spring Cloud Stream 架構中提供一個獨立的應用核心,它通過輸入(@Input)和輸出(@Output)通道與外部世界進行通信,消息源端(Source)通過輸入通道發送消息,消費目标端(Sink)通過監聽輸出通道來擷取消費的消息。這些通道通過專用的 Binder 實作與外部代理連接配接。開發人員的代碼隻需要針對應用核心提供的固定的接口和注解方式進行程式設計,而不需要關心運作時具體的 Binder 綁定的消息中間件。
在運作時,Spring Cloud Stream 能夠自動探測并使用在 classpath 下找到的 Binder。這樣開發人員可以輕松地在相同的代碼中使用不同類型的中間件:僅僅需要在建構時包含進不同的 Binder。在更加複雜的使用場景中,也可以在應用中打包多個 Binder 并讓它自己選擇 Binder,甚至在運作時為不同的通道使用不同的 Binder。
Binder 抽象使得 Spring Cloud Stream 應用可以靈活的連接配接到中間件,加之 Spring Cloud Stream 使用利用了 Spring Boot 的靈活配置配置能力,這樣的配置可以通過外部配置的屬性和 Spring Boot 支援的任何形式來提供(包括應用啟動參數、環境變量和 application.yml 或者 application.properties 檔案),部署人員可以在運作時動态選擇通道連接配接 destination(例如,RocketMQ 的 topic 或者 RabbitMQ 的 exchange)。
Spring Cloud Stream 屏蔽了底層消息中間件的實作細節,希望以統一的一套 API 來進行消息的發送/消費,底層消息中間件的實作細節由各消息中間件的 Binder 完成。Spring 官方實作了 Rabbit binder 和 Kafka Binder。Spring Cloud Alibaba 實作了 RocketMQ Binder[3],其主要實作原理是把發送消息最終代理給了 RocketMQ-Spring 的 RocketMQTemplate,在消費端則内部會啟動 RocketMQ-Spring Consumer Container 來接收消息。以此為基礎,Spring Cloud Alibaba 還實作了 Spring Cloud Bus RocketMQ, 使用者可以使用 RocketMQ 作為 Spring Cloud 體系内的消息總線,來連接配接分布式系統的所有節點。通過 Spring Cloud Stream RocketMQ Binder,RocketMQ 可以與 Spring Cloud 生态更好的結合。比如與 Spring Cloud Data Flow、Spring Cloud Funtion 結合,讓 RocketMQ 可以在 Spring 流計算生态、Serverless(FaaS) 項目中被使用。
如今 Spring Cloud Stream RocketMQ Binder 和 Spring Cloud Bus RocketMQ 做為 Spring Cloud Alibaba 的實作已登陸 Spring 的官網[4],Spring Cloud Alibaba 也成為 Spring Cloud 最活躍的實作。
三、如何在 Spring 生态中選擇 RocketMQ 實作?
通過介紹 Spring 中的消息架構,介紹了以 RocketMQ 為基礎與 Spring 消息架構結合的幾個項目,主要是 RocketMQ-Spring、Spring Cloud Stream RocketMQ Binder、Spring Cloud Bus RocketMQ、Spring Data Flow 和 Spring Cloud Function。它們之間的關系可以如下圖表示。
如何在實際業務開發中選擇相應項目進行使用?下面分别列出每個項目的特點和使用場景。
1. RocketMQ-Spring
特點:
- 作為起步依賴,簡單引入一個包就能在 Spring 生态用到 RocketMQ 用戶端的所有功能。
- 利用了大量自動配置和注解簡化了程式設計模型,并且支援 Spring Messaging API。
- 與 RocketMQ 原生 Java SDK 的功能完全對齊。
使用場景:
- 适合在 Spring Boot 中使用 RocketMQ 的使用者,希望能用到 RocketMQ 原生 java 用戶端的所有功能,并通過 Spring 注解和自動配置簡化程式設計模型。
2. Spring Cloud Stream RocketMQ Binder
- 屏蔽底層 MQ 實作細節,上層 Spring Cloud Stream 的 API 是統一的。如果想從 Kafka 切到 RocketMQ,直接改個配置即可。
- 與 Spring Cloud 生态整合更加友善。比如 Spring Cloud Data Flow,這上面的流計算都是基于 Spring Cloud Stream;Spring Cloud Bus 消息總線内部也是用的 Spring Cloud Stream。
- Spring Cloud Stream 提供的注解,程式設計體驗都是非常棒。
- 在代碼層面能完全屏蔽底層消息中間件的使用者,并且希望能項目能更好的接入 Spring Cloud 生态(Spring Cloud Data Flow、Spring Cloud Funtcion 等)。
3. Spring Cloud Bus RocketMQ
- 将 RocketMQ 作為事件的“傳輸器”,通過發送事件(消息)到消息隊列上,進而廣播到訂閱該事件(消息)的所有節點上,完成事件的分發和通知。
- 在 Spring 生态中希望用 RocketMQ 做消息總線的使用者,可以用在應用間事件的通信,配置中心用戶端重新整理等場景。
4. Spring Cloud Data Flow
- 以 Source/Processor/Sink 元件進行流式任務處理。RocketMQ 作為流處理過程中的中間存儲元件。
- 流處理,大資料處理場景。
5. Spring Cloud Function
- 消息的消費/生産/處理都是一次函數調用,融合 Java 生态的 Function 模型。
- Serverless 場景。
本文整體介紹了在 Spring 生态中接入 RockeMQ 的 5 種方法,讓各位開發者對幾種經典場景有宏觀的了解。後續會有專欄詳細介紹上述各個項目的具體使用方法和應用場景,真正地在 Spring 生态中玩轉 RocketMQ!
相關連結:
[1]
https://www.infoq.cn/article/G-og5V8x3BK8i4z90y6P [2] https://spring.io/blog/2020/02/25/spring-tips-apache-rocketmq [3] https://github.com/alibaba/spring-cloud-alibaba/wiki/RocketMQ [4] https://spring.io/projects/spring-cloud-alibaba