如何在Spring生態中玩轉RocketMQ?

www88jmpcom17I76934555發表於2021-03-29

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。它們之間的關係可以如下圖表示。

如何在實際業務開發中選擇相應專案進行使用?下面分別列出每個專案的特點和使用場景。

RocketMQ-Spring

特點:

  • 作為起步依賴,簡單引入一個包就能在Spring生態用到RocketMQ客戶端的所有功能。

  • 利用了大量自動配置和註解簡化了程式設計模型,並且支援Spring Messaging API。

  • 與RocketMQ 原生Java SDK的功能完全對齊。

使用場景:

  • 適合在Spring Boot中使用RocketMQ的使用者,希望能用到RocketMQ原生java客戶端的所有功能,並通過Spring註解和自動配置簡化程式設計模型。

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等)。

Spring Cloud Bus RocketMQ

特點:

  • 將RocketMQ作為事件的“傳輸器”,通過傳送事件(訊息)到訊息佇列上,從而廣播到訂閱該事件(訊息)的所有節點上,完成事件的分發和通知。

使用場景:

  • 在Spring生態中希望用RocketMQ做訊息匯流排的使用者,可以用在應用間事件的通訊,配置中心客戶端重新整理等場景。

Spring Cloud Data Flow

特點:

  • 以Source/Processor/Sink元件進行流式任務處理。RocketMQ作為流處理過程中的中間儲存元件。

使用場景:

  • 流處理,大資料處理場景。

Spring Cloud Function

特點:

  • 訊息的消費/生產/處理都是一次函式呼叫,融合Java生態的Function模型。

使用場景:

  • Serverless場景。
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章