天天看點

如何在Spring生态中玩轉RocketMQ?

如何在Spring生态中玩轉RocketMQ?

作者 | 通融、洛夜

來源 |

阿裡技術公衆号

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等子產品,涉及開發的各個領域。

如何在Spring生态中玩轉RocketMQ?

2014年4月1日,Spring Boot 1.0.0正式釋出。它基于“約定大于配置”(Convention over configuration)這一理念來快速地開發,測試,運作和部署Spring應用,并能通過簡單地與各種啟動器(如spring-boot-web-starter)結合,讓應用直接以指令行的方式運作,不需再部署到獨立容器中。Spring Boot的出現可以說是Spring架構的第二春,它不但簡化了開發的流程,目前更是事實标準。下面這幅圖可以看出相同功能的Spring和Spring Boot的代碼實作對比。

如何在Spring生态中玩轉RocketMQ?

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的自動化選項和一些定制化的屬性。

如何在Spring生态中玩轉RocketMQ?

在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生态中最活躍的消息項目。

如何在Spring生态中玩轉RocketMQ?

2 Spring Cloud Stream

Spring Cloud Stream結合了Spring Integration的注解和功能,它的應用模型如下:

如何在Spring生态中玩轉RocketMQ?

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

如何在Spring生态中玩轉RocketMQ?

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

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場景。

本文整體介紹了在Spring生态中接入RockeMQ的5種方法,讓各位開發者對幾種經典場景有宏觀的了解。後續會有專欄詳細介紹上述各個項目的具體使用方法和應用場景,真正地在Spring生态中玩轉RocketMQ!點選“閱讀原文”直達知行動手實驗室,直接上手體驗3個最常用的在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