版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
RocketMQ-Spring畢業(yè)兩周年,為什么能成為Spring生態(tài)中最受歡迎的方法一:使用rocketmq-spring-boot-starter來配置、發(fā)開篇:在Spring生態(tài)中玩轉(zhuǎn)RocketMQApacheRocketMQ作為阿里開源的業(yè)務(wù)消息的首選,通過雙11業(yè)務(wù)打磨,在消息和流處理領(lǐng)域被廣泛應(yīng)用。而微服務(wù)生態(tài)Spring框架也是業(yè)務(wù)開發(fā)中最受開發(fā)者歡迎的框架之一,兩者的完美契合使得RocketMQ成為SpringMessaing實現(xiàn)中最受歡迎的消息實現(xiàn)。在Spring生態(tài)中使用RocketMQ到底有多少種方式?他們各自適用于什么場景?各自有什么優(yōu)劣勢?如何開始實戰(zhàn)?本書將一一解答。我們先會帶領(lǐng)各位開發(fā)者:l回顧羅美琪(RocketMQ)和春波特(SpringBoot)故事開始的時候,rocketmq-spring經(jīng)過6個多月的孵化,作為ApacheRocketMQ的子項目正式畢業(yè)。l回顧rocketmq-spring畢業(yè)后的兩年,是如何成為Spring生態(tài)中最受歡迎的messaging實現(xiàn)的?最后將通過圖文和實操地方式帶來給位開發(fā)者玩轉(zhuǎn)在Spring生態(tài)中使用RocketMQ的三種主流方式。所有動手實操的部分大家可以登錄知行動手實驗室免費體驗。開卷有益,希望各位開發(fā)者通過閱讀本書、動手實操有所收獲。在介紹RocketMQ與Spring故事之前,不得不提到Spring中的兩個關(guān)于消息的框架,SpringMessaging和SpringCloudStream。它們都能夠與SpringBoot整合并提供了一些參考的實現(xiàn)。和所有的實現(xiàn)框架一樣,消息框架的目的是實現(xiàn)輕量級的消息驅(qū)動的微服務(wù),可以有效地簡化開發(fā)人員對消息中間件的使用復(fù)雜度,讓系統(tǒng)開發(fā)人員可以有更多的精力關(guān)注于核心業(yè)務(wù)邏輯的處理。SpringMessaging是SpringFramework4中添加的模塊,是Spring與消息系統(tǒng)集成的一個擴展性的支持。它實現(xiàn)了從基于JmsTemplate的簡單的使用JMS接口到異步接收消息的一整套完整的基礎(chǔ)架構(gòu),SpringAMQP提供了該協(xié)議所要求的類似的功能集。在與SpringBoot的集成后,它擁有了自動配置能力,能夠在測試和運行時與相應(yīng)的消息傳遞系統(tǒng)進行集成。單純對于客戶端而言,SpringMessaging提供了一套抽象的API或者說是約定的標(biāo)準(zhǔn),對消息發(fā)送端和消息接收端的模式進行規(guī)定,比如消息Messaging對應(yīng)的模型就包括一個消息體Payload和消息頭Header。不同的消息中間件提供商可以在這個模式下提供自己的Spring實現(xiàn):在消息發(fā)送端需要實現(xiàn)的是一個XXXTemplate形式的JavaBean,結(jié)合SpringBoot的自動化配置選項提供多個不同的發(fā)送消息方法;在消息的消費端是一個XXXMessageListener接口(實現(xiàn)方式通常會使用一個注解來聲明一個消息驅(qū)動的POJO提供回調(diào)方法來監(jiān)聽和消費消息,這個接口同樣可以使用SpringBoot的自動化選項和一些定制化的屬性。在ApacheRocketMQ生態(tài)中,RocketMQ-Spring-Boot-Starter(下文簡稱RocketMQ-Spring)就是一個支持SpringMessagingAPI標(biāo)準(zhǔn)的項目。該項目把RocketMQ的客戶端使用SpringBoot的方式進行了封裝,可以讓用戶通過簡單的annotation和標(biāo)準(zhǔn)的SpringMessagingAPI編寫代碼來進行消息的發(fā)送和消費,也支持?jǐn)U展出RocketMQ原生API來支持更加豐富的消息類型。在RocketMQ-Spring畢業(yè)初期,RocketMQ社區(qū)同學(xué)請Spring社區(qū)的同學(xué)對RocketMQ-Spring代碼進行review,引出一段羅美琪(RocketMQ)和春波特(SpringBoot)故事的佳話[1],著名Spring布道師JoshLong向國外同學(xué)介紹如何使用RocketMQ-Spring收發(fā)消息[2]。RocketMQ-Spring也在短短兩年時間超越Spring-Kafka和Spring-AMQP(注:兩者均由Spring社區(qū)維護成為SpringMessaging生態(tài)中最活躍的消息項目。SpringCloudStream結(jié)合了SpringIntegration的注解和功能,它的應(yīng)用模型如下:SpringCloudStream框架中提供一個獨立的應(yīng)用內(nèi)核,它通過輸入(@Input)和輸出(@Output)通道與外部世界進行通信,消息源端(Source)通過輸入通道發(fā)送消息,消費目標(biāo)端(Sink)通過監(jiān)聽輸出通道來獲取消費的消息。這些通道通過專用的Binder實現(xiàn)與外部代理連接。開發(fā)人員的代碼只需要針對應(yīng)用內(nèi)核提供的固定的接口和注解方式進行編程,而不需要關(guān)心運行時具體的Binder綁定的消息中間件。在運行時,SpringCloudStream能夠自動探測并使用在classpath下找到的Binder。這樣開發(fā)人員可以輕松地在相同的代碼中使用不同類型的中間件:僅僅需要在構(gòu)建時包含進不同的Binder。在更加復(fù)雜的使用場景中,也可以在應(yīng)用中打包多個Binder并讓它自己選擇Binder,甚至在運行時為不同的通道使用不同的Binder。Binder抽象使得SpringCloudStream應(yīng)用可以靈活的連接到中間件,加之SpringCloudStream使用利用了SpringBoot的靈活配置配置能力,這樣的配置可以通過外部配置的屬性和SpringBoot支持的任何形式來提供(包括應(yīng)用啟動參數(shù)、環(huán)境變量和application.yml或者perties文件部署人員可以在運行時動態(tài)選擇通道連接destination(例如,RocketMQ的topic或者RabbitMQ的exchange)。SpringCloudStream屏蔽了底層消息中間件的實現(xiàn)細(xì)節(jié),希望以統(tǒng)一的一套API來進行消息的發(fā)送/消費,底層消息中間件的實現(xiàn)細(xì)節(jié)由各消息中間件的Binder完成。Spring官方實現(xiàn)了Rabbitbinder和KafkaBinder。SpringCloudAlibaba實現(xiàn)了RocketMQBinder[3],其主要實現(xiàn)原理是把發(fā)送消息最終代理給了RocketMQ-Spring的RocketMQTemplate,在消費端則內(nèi)部會啟動RocketMQ-SpringConsumerContainer來接收消息。以此為基礎(chǔ),SpringCloudAlibaba還實現(xiàn)了SpringCloudBusRocketMQ,用戶可以使用RocketMQ作為SpringCloud體系內(nèi)的消息總線,來連接分布式系統(tǒng)的所有節(jié)點。通過SpringCloudStreamRocketMQBinder,RocketMQ可以與SpringCloud生態(tài)更好的結(jié)合。比如與SpringCloudDataFlow、SpringCloudFuntion結(jié)合,讓RocketMQ可以在Spring流計算生態(tài)、Serverless(FaaS)項目中被使用。如今SpringCloudStreamRocketMQBinder和SpringCloudBusRocketMQ做為SpringCloudAlibaba的實現(xiàn)已登陸Spring的官網(wǎng)[4],SpringCloudAlibaba也成為SpringCloud最活躍的實現(xiàn)。通過介紹Spring中的消息框架,介紹了以RocketMQ為基礎(chǔ)與Spring消息框架結(jié)合的幾個項目,主要是RocketMQ-Spring、SpringCloudStreamRocketMQBinder、SpringCloudBusRocketMQ、SpringDataFlow和SpringCloudFunction。它們之間的關(guān)系可以如下圖表示。如何在實際業(yè)務(wù)開發(fā)中選擇相應(yīng)項目進行使用?下表列出了每個項目的特點和使用場景。項目特點使用場景RocketMQ-Spring1.作為起步依賴,簡單引入一個包就能在Spring生態(tài)用到RocketMQ客戶端的所有功能。2.利用了大量自動配置和注解簡化了編程模型,并且支持SpringMessagingAPI3.與RocketMQ原生JavaSDK的功能完全對齊Boot中使用Rock望能用到RocketMQ原生java客戶端的所有功能,并通過Spring注解和自動配置簡化編程模型。SpringCloudStreamRocketMQ1.屏蔽底層MQ實現(xiàn)細(xì)節(jié),上層SpringCloud Stream的API是統(tǒng)一的。如果想從Kafka切到RocketMQ,直接改個配置即可。2.與SpringCloud生態(tài)整合更加方便。比如SpringCloudDataFlow,這上面的流計算都是基于SpringCloudStream;SpringCloudBus消息總線內(nèi)部也是用的SpringCloudStream。3.SpringCloudStream提供的注解,編程體驗都是非常棒。在代碼層面能完全屏蔽底層消息中間件的用戶,并且希望能項目能更好的接入SpringCloud生態(tài)(SaFlow、SpringCloudFuntcion等)。項目特點使用場景SpringCloud將RocketMQ作為事件的“傳輸器”,通過發(fā)送事件(消息)到消息隊列上,從而廣播到訂閱該事件(消息)的所有節(jié)點上。完成事件的分發(fā)和通知。在Spring生態(tài)中希望用RocketMQ做消息總線的用戶,可以用在應(yīng)用間事件的通信,配置中心客戶端刷新等場景SpringCloud以Source/Processor/Sink組件進行流式任務(wù)處理。RocketMQ作為流處理過程中的中間存儲組件流處理,大數(shù)據(jù)處理場景SpringCloudFunction消息的消費/生產(chǎn)/處理都是一次函數(shù)調(diào)用,融合Java生態(tài)的Function模型Serverless場景RocketMQ作為業(yè)務(wù)消息的首選,在消息和流處理領(lǐng)域被廣泛應(yīng)用。而微服務(wù)生態(tài)Spring框架也是業(yè)務(wù)開發(fā)中最被,兩者的完美契合使得RocketMQ成為SpringMessaing實現(xiàn)中最受歡迎的消息實現(xiàn)。書的后半部分講給各位開發(fā)者詳細(xì)講述在Spring生態(tài)中使用RocketMQ的三種主流的方式。RocketMQSpring最初的故事:羅美琪和春波特的故事...作者:遼天rocketmq-spring經(jīng)過6個多月的孵化,作為ApacheRocketMQ的子項目正式畢業(yè),發(fā)布了第一個Release版本2.0.1。這個項目是把RocketMQ的客戶端使用SpringBoot的方式進行了封裝,可以讓用戶通過簡單的annotation和標(biāo)準(zhǔn)的SpringMessagingAPI編寫代碼來進行消息的發(fā)送和消費。在項目發(fā)布階段我們很榮幸的邀請了Spring社區(qū)的原創(chuàng)人員對我們的代碼進行了Review,通過幾輪slack上的深入交流感受到了Spring團隊對開源代碼質(zhì)量的標(biāo)準(zhǔn),對SpringBoot項目細(xì)節(jié)的要求。本文是對Review和代碼改進過程中的經(jīng)驗和技巧的總結(jié),希望從事SpringBoot開發(fā)的同學(xué)有幫助。我們把這個過程整理成RocketMQ社區(qū)的貢獻者羅美琪和Spring社區(qū)的春波特(SpringBoot)的故事。故事的開始是這樣的,羅美琪美眉有一套RocketMQ的客戶端代碼,負(fù)責(zé)發(fā)送消息和消費消息。早早的聽說春波特小哥哥的大名,通過SpringBoot可以把自己客戶端調(diào)用變得非常簡單,只使用一些簡單的注解(annotation)和代碼就可以使用獨立應(yīng)用的方式啟動,省去了復(fù)雜的代碼編寫和參數(shù)配置。聰明的她參考了業(yè)界已經(jīng)實現(xiàn)的消息組件的Spring實現(xiàn)了一個RocketMQSpring客戶端:1.需要一個消息的發(fā)送客戶端,它是一個自動創(chuàng)建的SpringBean,并且相關(guān)屬性要能夠根據(jù)配置文件的配置自動設(shè)置,命名它為:RocketMQTemplate,同時讓它封裝發(fā)送消息的各種同步和異步的方法。2.需要消息的接收客戶端,它是一個能夠被應(yīng)用回調(diào)的Listener,來將消費消息回調(diào)給用戶進行相關(guān)的處理。}}特別說明一下:這個消費客戶端Listener需要通過一個自定義的注解。@RocketMQMessageListener來標(biāo)注,這個注解的作用有兩個:l定義消息消費的配置參數(shù)(如:消費的topic,是否順序消費,消費組等);l可以讓spring-boot在啟動過程中發(fā)現(xiàn)標(biāo)注了這個注解的所有Listener,并進行初始化,詳見ListenerContainerConfiguration類及其實現(xiàn)SmartInitializingSingleton的接口方法afterSingletonsInstantiated()。通過研究發(fā)現(xiàn),Spring-Boot最核心的實現(xiàn)是自動化配置(autoconfiguration),它需要分為三個部分:lAutoConfiguration類,它由@Configuration標(biāo)注,用來創(chuàng)建RocketMQ客戶端所需要的SpringBean,如上面所提到的RocketMQTemplate和能夠處理消費回調(diào)MQPushConsumer,并將來將監(jiān)聽到的消費消息并推送給Listener進行回調(diào)。可參考RocketMQAutoConfiguration.java(編者注:這個是最終發(fā)布的類,沒有review的痕跡啦)l上面定義的Configuration類,它本身并不會“自動”配置,需要由META-INF/spring.factories來聲明,可參考spring.factories使用這個META配置的好處是上層用戶不需要關(guān)心自動配置類的細(xì)節(jié)和開關(guān),只要classpath中有這個META-INF文件和Configuration類,即可自動配置。l另外,上面定義的Configuration類,還定義了@EnableConfiguraitonProperties注解來引入ConfigurationProperties類,它的作用是定義自動配置的屬性,可參考RocketMQProperties.java上層用戶可以根據(jù)這個類里定義的屬性來配置相關(guān)的屬性文件(即META-INF/perties或META-INF/application.yaml)羅美琪美眉按照這個思路開發(fā)完成了RocketMQSpringBoot封裝并形成了starter交給社區(qū)的小伙伴們試用,nice,大家使用后反饋效果不錯。但是還是想請教一下專業(yè)的春波特小哥哥,看看他的意見。春波特小哥哥相當(dāng)?shù)呢?fù)責(zé)地對羅美琪的代碼進行了Review,首先他拋出了兩個鏈接:/spring-projects/spring-boot/wiki/Building-On-Spring-Boothttps://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html然后解釋道:"在SpringBoot中包含兩個概念:auto-configuration和starter-POMs,它們之間相互關(guān)聯(lián),但是不是簡單綁定在一起的:a.auto-configuration負(fù)責(zé)響應(yīng)應(yīng)用程序的當(dāng)前狀態(tài)并配置適當(dāng)?shù)腟pringBean。它放在用戶的CLASSPATH中結(jié)合在CLASSPATH中的其它依賴就可以提供相關(guān)的功能;b.Starter-POM負(fù)責(zé)把auto-configuration和一些附加的依賴組織在一起,提供開箱即用的功能,它通常是一個mavenproject,里面只是一個POM文件,不需要包含任何附加的classes或resources.換句話說,starter-POM負(fù)責(zé)配置全量的classpath,而auto-configuration負(fù)責(zé)具體的響應(yīng)(實現(xiàn));前者是total-solution,后者可以按需使用。你現(xiàn)在的系統(tǒng)是單一的一個module把auto-configuration和starter-POM混在了一起,這個不利于以后的擴展和模塊的單獨使用。"羅美琪了解到了區(qū)分確實對日后的項目維護很重要,于是將代碼進行了模塊化|---rocketmq-spri|---rocketmq-spring-bootauto-configuraiton模塊|---rocketmq-spring-staterstarter模塊(實際上只包含一個pom.xml文件)|---rocketmq-spring-samples調(diào)用starter的示例樣本"很好,這樣的模塊結(jié)構(gòu)就清AutoConfiguration文件里的一些標(biāo)簽的用法并不正確,幫你注釋一下,另外,考慮到Spring官方到明年8月SpringBoot1.X將不再提供支持,所以建議實現(xiàn)直接支持SpringBoot2.X"}}}}}}注[1]:在聲明屬性的時候不要使用駝峰命名法,要使用-橫線分隔,這樣才能支持屬性名的松散規(guī)則(relaxedrules)。注[2]:BeanPostProcessor接口作用是:如果需要在Spring容器完成Bean的實例化、配置和其他的初始化的前后添加一些自己的邏輯處理,就可以定義一個或者多個BeanPostProcessor接口的實現(xiàn),然后注冊到容器中。為什么建議聲明成static的,春波特的英文原文:Iftheydon'twebasicallyregisterthepost-processoratthesame"time"asalltheotherbeansinthatclassandthecontractofBPPisthatitmustberegisteredveryearlyon.ThismaynotmakeadifferenceforthisparticularclassbutflaggingitasstaticasthesideeffecttomakeclearyourBPPimplementationisnotsupposedtodragotherbeansviadependencyinjection.AutoConfiguration里果真很有學(xué)問,羅美琪迅速的調(diào)整了代碼,一下看起來清爽了許多。不過還是被春波特提出了兩點建議:}}}}}注[3]:使用GenericApplicationContext.registerBean的方式Class<T>beanClass,Supplier<T>supplier,BeanDefinitionCustomizer…ustomizers)"還有,還有",在羅美琪采納了春波特的意見比較大地調(diào)整了代碼之后,春波特哥哥有提出了SpringBoot特有的幾個要求:l使用Spring的Assert在傳統(tǒng)的Java代碼中我們使用assert進行斷言,SpringBoot中斷言需要使用它自有的Assert類,如下示例:lAutoConfiguration單元測試使用Spring2.0提供的ApplicationContextRunner}l在auto-configuration模塊的pom.xml文件里,加入spring-boot-configuration-processor注解處理器,這樣它能夠生成輔助元數(shù)據(jù)文件,加快啟動時間。詳情見這里(https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html#boot-features-custom-starter-module-autoconfigure)。最后,春波特還相當(dāng)專業(yè)地向羅美琪美眉提供了如下兩方面的意見:注釋與命名規(guī)范我們常用的代碼注釋分為多行(/**…*/)和單行(//...)兩種類型,對于需要說明的成員變量,方法或者代碼邏輯應(yīng)該提供多行注釋;有些簡單的代碼邏輯注釋也可以使用單行注釋。在注釋時通用的要求是首字母大寫開頭,并且使用句號結(jié)尾;對于單行注釋,也要求首字母大寫開頭;并且不建議行尾單行注釋。在變量和方法命名時盡量用詞準(zhǔn)確,并且盡量不要使用縮寫,如:sendMsgTimeout,建議寫成sendMessageTimeout;包名supports,建議改成support。是否需要使用Lombok使用Lombok的好處是代碼更加簡潔,只需要使用一些注釋就可省略constructor,setter和getter等諸多方法(bolierplatecode);但是也有一個壞處就是需要開發(fā)者在自己的IDE環(huán)境配置Lombok插件來支持這一功能,所以Spring社區(qū)的推薦方式是不使用Lombok,以便新用戶可以直接查看和維護代碼,不依賴IDE的設(shè)置。對于包名(package)的控制如果一個包目錄下沒有任何class,建議要去掉這個包目錄。例如:org.apache.rocketmq.spring.starter在spring目錄下沒有具體的class定義,那么應(yīng)該去掉這層目錄(編者注:我們最終把package改為org.apache.rocketmq.spring,將starter下的目錄和classes上移一層)。我們把所有Enum類放在包org.apache.rocketmq.spring.enums下,這個包命名并不規(guī)范,需要把Enum類調(diào)整到具體的包中,去掉enums包;類的隱藏,對于有些類,它只被包中的其它類使用,而不需要把具體的使用細(xì)節(jié)暴漏給最終用戶,建議使用packageprivate約束,例如:TransactionHandler類。不建議使用StaticImport,雖然使用它的好處是更少的代碼,壞處是破壞程序的可讀性和易維護性。一個類的static方法不要結(jié)合final,除非這個這個類本身是final并且聲明private構(gòu)造(ctor),如果兩者結(jié)合以為這子類不能再(hiding)定義該方法,給將來的擴展和子類調(diào)用帶來麻煩。在配置文件聲明的Bean盡量使用構(gòu)造函數(shù)或者Setter方法設(shè)置成員變量,而不要不要額外初始化無用的成員變量。如果一個方法沒有任何地方調(diào)用,就應(yīng)該刪除;如果一個接口方法不需要,就不要實現(xiàn)這個接口類注[4]:下面的截圖是有FieldInjection轉(zhuǎn)變成構(gòu)造函數(shù)設(shè)置的代碼示例:轉(zhuǎn)換成:羅美琪根據(jù)上述的要求調(diào)整了代碼,使代碼質(zhì)量有了很大的提高,并且總結(jié)了SpringBoot開發(fā)的要點:l編寫前參考成熟的springboot實現(xiàn)代碼。l要注意模塊的劃分,區(qū)分autoconfiguration和starter。l在編寫autoconfigurationBean的時候,注意@Conditional注解的使用;盡量使用構(gòu)造器或者setter方法來設(shè)置變量,避免使用FieldInjection方式;多個AutoConfigruation測試類。l注意一些細(xì)節(jié):static與BeanPostProcessor;Lifecycle的使用;不必要的成員屬性的初始化等。通過本次的Review工作了解到了spring-boot及auto-configuration所需要的一些約束條件,信心滿滿地提交了最終的代碼,又可以邀請RocketMQ社區(qū)的小伙伴們一起使用rocketmq-spring功能了,廣大讀者可以在參考代碼庫查看到最后修復(fù)代碼,也希望有更多的寶貴意見反饋和加強,加油!開源軟件不僅僅是提供一個好用的產(chǎn)品,代碼質(zhì)量和風(fēng)格也會影響到廣大的開發(fā)者,活躍的社區(qū)貢獻者羅美琪還在與RocketMQ社區(qū)的小伙伴們不斷完善spring的代碼,并邀請春波特的Spring社區(qū)進行宣講和介紹,下一步將rocketmq-spring-starter推進到SpringInitializr,讓用戶可以直接在/bootstrap.html網(wǎng)站上像使用其它starter(如:Tomcatstarter)一樣使用rocketmq-spring.RocketMQ-Spring畢業(yè)兩周年,為什么能成為Spring生態(tài)中最受歡迎的messaging實現(xiàn)2019年1月,孵化6個月的RocketMQ-Spring作為ApacheRocketMQ的子項目正式畢業(yè),發(fā)布了第一個Release版本2.0.1。該項目是把RocketMQ的客戶端使用SpringBoot的方式進行了封裝,可以讓用戶通過簡單的annotation和標(biāo)準(zhǔn)的SpringMessagingAPI編寫代碼來進行消息的發(fā)送和消費。當(dāng)時RocketMQ社區(qū)同學(xué)羅美琪(RocketMQ)和春波特(SpringBoot)的故事。時隔兩年,RocketMQ-Spring正式發(fā)布2.2.0。在這期間,RocketMQ-Spring迭代了數(shù)個版本,以RocketMQ-Spring為基礎(chǔ)實現(xiàn)的SpringCloudStreamRocketMQBinder、SpringCloudBusRocketMQ登上了Spring的官網(wǎng),Spring布道師baeldung向國外同學(xué)介紹如何使用RocketMQ-Spring,越來越多國內(nèi)外的同學(xué)開始使用RocketMQ-Spring收發(fā)消息,RocketMQ-Spring倉庫的star數(shù)也在短短兩年時間內(nèi)超越了Spring-Kafka和Spring-AMQP(注:兩者均由Spring社區(qū)維護成為ApacheRocketMQ最受歡迎的生態(tài)項目之一。RocketMQ-Spring的受歡迎一方面得益于支持豐富業(yè)務(wù)場景的RocketMQ與微服務(wù)生態(tài)Spring的完美契合,另一方面也與RocketMQ-Spring本身嚴(yán)格遵循SpringMessagingAPI規(guī)范,支持豐富的消息類型分不開。SpringMessaging提供了一套抽象的API,對消息發(fā)送端和消息接收端的模式進行規(guī)定,不同的消息中間件提供商可以在這個模式下提供自己的Spring實現(xiàn):在消息發(fā)送端需要實現(xiàn)的是一個XXXTemplate形式的JavaBean,結(jié)合SpringBoot的自動化配置選項提供多個不同的發(fā)送消息方法;在消息的消費端是一個XXXMessageListener接口(實現(xiàn)方式通常會使用一個注解來聲明一個消息驅(qū)動的POJO提供回調(diào)方法來監(jiān)聽和消費消息,這個接口同樣可以使用SpringBoot的自動化選項和一些定制化的屬性。RocketMQ-Spring在遵循SpringMessagingAPI規(guī)范的基礎(chǔ)上結(jié)合RocketMQ自身的功能特點提供了相應(yīng)的API。在消息的發(fā)送端,RocketMQ-Spring通過實現(xiàn)RocketMQTemplate完成消息的發(fā)送。如下圖所示,RocketMQTemplate繼承AbstractMessageSendingTemplate抽象類,來支持SpringMessagingAPI標(biāo)準(zhǔn)的消息轉(zhuǎn)換和發(fā)送方法,這些方法最終會代理給doSend方法,doSend方法會最終調(diào)用syncSend,由DefaultMQProducer實現(xiàn)。除SpringMessagingAPI規(guī)范中的方法,RocketMQTemplate還實現(xiàn)了RocketMQ原生客戶端的一些方法,來支持更加豐富的消息類型。值得注意的是,相比于原生客戶端需要自己去構(gòu)建RocketMQMessage(比如將對象序列化成byte數(shù)組放入Message對象RocketMQTemplate可以直接將對象、字符串或者byte數(shù)組作為參數(shù)發(fā)送出去(對象序列化操作由RocketMQ-Spring內(nèi)置完成在消費端約定好對應(yīng)的Schema即可正常收發(fā)。……在消費端,需要實現(xiàn)一個包含@RocketMQMessageListener注解的類(需要實現(xiàn)RocketMQListener接口,并實現(xiàn)onMessage方法,在注解中進行topic、consumerGroup等屬性配置這個Listener會一對一的被放置到DefaultRocketMQListenerContainer容器對象中,容器對象會根據(jù)消費的方式(并發(fā)或順序),將RocketMQListener封裝到具體的RocketMQ內(nèi)部的并發(fā)或者順序接口實現(xiàn)。在容器中創(chuàng)建RocketMQDefaultPushConsumer對象,啟動并監(jiān)聽定制的Topic消息,完成約定Schema對象的轉(zhuǎn)換,回調(diào)到Listener的onMessage方法。}}除此Push接口之外,在最新的2.2.0版本中,RocketMQ-Spring實現(xiàn)了RocketMQLitePullConsumer。通過在配置文件中進行consumer的配置,利用RocketMQTemplate的Recevie方法即可主動Pull消息。}RocketMQSpring消息類型支持方面與RocketMQ原生客戶端完全對齊,包括同步/異步/one-way、順序、延遲、批量、事務(wù)以及Request-Reply消息。在這里,主要介紹較為特殊的事務(wù)消息和request-reply消息。RocketMQ的事務(wù)消息不同于SpringMessaging中的事務(wù)消息,依然采用RocketMQ原生事務(wù)消息的方案。如下所示,發(fā)送事務(wù)消息時需要實現(xiàn)一個包含@RocketMQTransactionListener注解的類,并實現(xiàn)executeLocalTransaction和checkLocalTransaction方法,從而來完成執(zhí)行本地事務(wù)以及檢查本地事務(wù)執(zhí)行結(jié)果。{}}}在2.1.0版本中,RocketMQ-Spring重構(gòu)了事務(wù)消息的實現(xiàn),如下圖所示,舊版本中每一個group對應(yīng)一個TransactionProducer,而在新版本中改為每一個RocketMQTemplate對應(yīng)一個TransationProducer,從而解決了并發(fā)使用多個事務(wù)消息的問題。當(dāng)用戶需要在單進程使用多個事務(wù)消息時,可以使用ExtRocketMQTemplate來完成(一般情況下,推薦一個進程使用一個RocketMQTemplate,ExtRocketMQTemplate可以使用在同進程中需要使用多個Producer/LitePullConsumer的場景,可以為ExtRocketMQTemplate指定與標(biāo)準(zhǔn)模版RocketMQTemplate不同的nameserver、group等配置并在對應(yīng)的RocketMQTransactionListener注解中指定rocketMQTemplateBeanName為ExtRocketMQTemplate的BeanName。在2.1.0版本中,RocketMQ-Spring開始支持Request-Reply消息。Request-Reply消息指的是上游服務(wù)投遞消息后進入等待被通知的狀態(tài),直到消費端返回結(jié)果并返回給發(fā)送端。在RocketMQ-Spring中,發(fā)送端通過RocketMQTemplate的sendAndReceivce方法進行發(fā)送,如下所示,主要有同步和異步兩種方式。異步方式中通過實現(xiàn)RocketMQLocalRequestCallback進行回調(diào)?!瓆}在消費端,仍然需要實現(xiàn)一個包含@RocketMQMessageListener注解的類,但需要實現(xiàn)的接口是RocketMQReplyListener<T,R>接口(普通消息為RocketMQListener<T>接口其中T表示接收值的類型,R表示返回值的類型,接口需要實現(xiàn)帶返回值的onMessage方法,返回值的內(nèi)容返回給對應(yīng)的Producer。}}RocketMQ-Spring遵循Spring約定大于配置(Conventionoverconfiguration)的理念,通過啟動器(SpringBootStarter)的方式,在pom文件引入依賴(groupId:org.apache.rocketmq,artifactId:rocketmq-spring-boot-starter)便可以在SpringBoot中集成所有RocketMQ客戶端的所有功能,通過簡單的注解使用即可完成消息的收發(fā)。在RocketMQ-SpringGithubWiki中有更加詳細(xì)的用法和常見問題解答。據(jù)統(tǒng)計,從RocketMQ-Spring發(fā)布第一個正式版本以來,RocketMQ-Spring完成16個bug修復(fù),37個imporvement,其中包括事務(wù)消息重構(gòu),消息過濾、消息序列化、多實例RocketMQTemplate優(yōu)化等重要優(yōu)化,歡迎更多的小伙伴能參與到RocketMQ社區(qū)的建設(shè)中來,羅美琪(RocketMQ)和春波特(SpringBoot)的故事還在繼續(xù)...方法一:使用rocketmq-spring-boot-starter來配置、發(fā)送和消費RocketMQ消息作者:遼天本文將對rocktmq-spring-boot的設(shè)計實現(xiàn)做一個簡單的介紹,讀者可以通過本文了解將RocketMQClient端集成為spring-boot-starter框架的開發(fā)細(xì)節(jié),然后通過一個簡單的示例來一步一步的講解如何使用這個spring-boot-starter工具包來配置,發(fā)送和消費RocketMQ消息。本文配套可交互教程已登錄阿里云知行動手實驗室,PC端登錄在瀏覽器中立即體驗。作者簡介:遼天,阿里巴巴技術(shù)專家,ApacheRocketMQ內(nèi)核控,擁有多年分布式系統(tǒng)研發(fā)經(jīng)驗,對Microservice、Messaging和Storage等領(lǐng)域有深刻理解,目前專注RocketMQ內(nèi)核優(yōu)化以及Messaging生態(tài)建設(shè)。通過本文,您將了解到:lSpring的消息框架介紹lrocketmq-spring-boot具體實現(xiàn)l使用示例上世紀(jì)90年代末,隨著JavaEE(EnterpriseEdition)的出現(xiàn),特別是EnterpriseJavaBeans的使用需要復(fù)雜的描述符配置和死板復(fù)雜的代碼實現(xiàn),增加了廣大開發(fā)者的學(xué)習(xí)曲線和開發(fā)成本,由此基于簡單的XML配置和普通Java對象(PlainOldJavaObjects)的Spring技術(shù)應(yīng)運而生,依賴注入(DependencyInjection),控制反轉(zhuǎn)(InversionofControl)和面向切面編程(AOP)的技術(shù)更加敏捷地解決了傳統(tǒng)Java企業(yè)及版本的不足。隨著Spring的持續(xù)演進,基于注解(Annotation)的配置逐漸取代了XML文件配置,2014年4月1日,SpringBoot1.0.0正式發(fā)布,它基于“約定大于配置”(Conventionoverconfiguration)這一理念來快速地開發(fā)、測試、運行和部署Spring應(yīng)用,并能通過簡單地與各種啟動器(如spring-boot-web-starter)結(jié)合,讓應(yīng)用直接以命令行的方式運行,不需再部署到獨立容器中。這種簡便直接快速構(gòu)建和開發(fā)應(yīng)用的過程,可以使用約定的配置并且簡化部署,受到越來越多的開發(fā)者的歡迎。ApacheRocketMQ是業(yè)界知名的分布式消息和流處理中間件,簡單地理解,它由Broker服務(wù)器和客戶端兩部分組成:其中客戶端一個是消息發(fā)布者客戶端(Producer),它負(fù)責(zé)向Broker服務(wù)器發(fā)送消息;另外一個是消息的消費者客戶端(Consumer),多個消費者可以組成一個消費組,來訂閱和拉取消費Broker服務(wù)器上存儲的消息。為了利用SpringBoot的快速開發(fā)和讓用戶能夠更靈活地使用RocketMQ消息客戶端,ApacheRocketMQ社區(qū)推出了spring-boot-starter實現(xiàn)。隨著分布式事務(wù)消息功能在RocketMQ4.3.0版本的發(fā)布,近期升級了相關(guān)的spring-boot代碼,通過注解方式支持分布式事務(wù)的回查和事務(wù)消息的發(fā)送。本文將對當(dāng)前的設(shè)計實現(xiàn)做一個簡單的介紹,讀者可以通過本文了解將RocketMQClient端集成為spring-boot-starter框架的開發(fā)細(xì)節(jié),然后通過一個簡單的示例來一步一步的講解如何使用這個spring-boot-starter工具包來配置,發(fā)送和消費RocketMQ消息。順便在這里討論一下在Spring中關(guān)于消息的兩個主要的框架,即SpringMessaging和SpringCloudStream。它們都能夠與SpringBoot整合并提供了一些參考的實現(xiàn)。和所有的實現(xiàn)框架一樣,消息框架的目的是實現(xiàn)輕量級的消息驅(qū)動的微服務(wù),可以有效地簡化開發(fā)人員對消息中間件的使用復(fù)雜度,讓系統(tǒng)開發(fā)人員可以有更多的精力關(guān)注于核心業(yè)務(wù)邏輯的處理。SpringMessaging是SpringFramework4中添加的模塊,是Spring與消息系統(tǒng)集成的一個擴展性的支持。它實現(xiàn)了從基于JmsTemplate的簡單的使用JMS接口到異步接收消息的一整套完整的基礎(chǔ)架構(gòu),SpringAMQP提供了該協(xié)議所要求的類似的功能集。在與SpringBoot的集成后,它擁有了自動配置能力,能夠在測試和運行時與相應(yīng)的消息傳遞系統(tǒng)進行集成。單純對于客戶端而言,SpringMessaging提供了一套抽象的API或者說是約定的標(biāo)準(zhǔn),對消息發(fā)送端和消息接收端的模式進行規(guī)定,不同的消息中間件提供商可以在這個模式下提供自己的Spring實現(xiàn):在消息發(fā)送端需要實現(xiàn)的是一個XXXTemplate形式的JavaBean,結(jié)合SpringBoot的自動化配置選項提供多個不同的發(fā)送消息方法;在消息的消費端是一個XXXMessageListener接口(實現(xiàn)方式通常會使用一個注解來聲明一個消息驅(qū)動的POJO),提供回調(diào)方法來監(jiān)聽和消費消息,這個接口同樣可以使用SpringBoot的自動化選項和一些定制化的屬性。如果有興趣深入的了解SpringMessaging及針對不同的消息產(chǎn)品的使用,推薦閱讀這個文件。參考SpringMessaging的既有實現(xiàn),RocketMQ的spring-boot-starter中遵循了相關(guān)的設(shè)計模式并結(jié)合RocketMQ自身的功能特點提供了相應(yīng)的API(如,順序,異步和事務(wù)半消息等)。SpringCloudStream結(jié)合了SpringIntegration的注解和功能,它的應(yīng)用模型如下:該圖片引自springcloudstreamSpringCloudStream框架中提供一個獨立的應(yīng)用內(nèi)核,它通過輸入(@Input)和輸出(@Output)通道與外部世界進行通信,消息源端(Source)通過輸入通道發(fā)送消息,消費目標(biāo)端(Sink)通過監(jiān)聽輸出通道來獲取消費的消息。這些通道通過專用的Binder實現(xiàn)與外部代理連接。開發(fā)人員的代碼只需要針對應(yīng)用內(nèi)核提供的固定的接口和注解方式進行編程,而不需要關(guān)心運行時具體的Binder綁定的消息中間件。在運行時,SpringCloudStream能夠自動探測并使用在classpath下找到的Binder。這樣開發(fā)人員可以輕松地在相同的代碼中使用不同類型的中間件:僅僅需要在構(gòu)建時包含進不同的Binder。在更加復(fù)雜的使用場景中,也可以在應(yīng)用中打包多個Binder并讓它自己選擇Binder,甚至在運行時為不同的通道使用不同的Binder。Binder抽象使得SpringCloudStream應(yīng)用可以靈活的連接到中間件,加之SpringCloudStream使用利用了SpringBoot的靈活配置配置能力,這樣的配置可以通過外部配置的屬性和SpringBoo支持的任何形式來提供(包括應(yīng)用啟動參數(shù)、環(huán)境變量和application.yml或者perties文件),部署人員可以在運行時動態(tài)選擇通道連接destination(例如,Kafka的topic或者RabbitMQ的exchange)。BinderSPI的方式來讓消息中間件產(chǎn)品使用可擴展的API來編寫相應(yīng)的Binder,并集成到SpringCloudSteam環(huán)境,目前RocketMQ還沒有提供相關(guān)的Binder,我們計劃在下一步將完善這一功能,也希望社區(qū)里有這方面經(jīng)驗的同學(xué)積極嘗試,貢獻PR或建議。在開始的時候我們已經(jīng)知道,springbootstarter構(gòu)造的啟動器對于使用者是非常方便的,使用者只要在pom.xml引入starter的依賴定義,相應(yīng)的編譯,運行和部署功能就全部自動引入。因此常用的開源組件都會為Spring的用戶提供一個spring-boot-starter封裝給開發(fā)者,讓開發(fā)者非常方便集成和使用,這里我們詳細(xì)的介紹一下RocketMQ(客戶端)的starter實現(xiàn)過程。對于一個spring-boot-starter實現(xiàn)需要包含如下幾個部分:在pom.xml的定義l定義最終要生成的starter組件信息l定義依賴包它分為兩個部分:A、Spring自身的依賴包;B、RocketMQ的依賴包配置文件類定義應(yīng)用屬性配置文件類RocketMQProperties,這個Bean定義一組默認(rèn)的屬性值。用戶在使用最終的starter時,可以根據(jù)這個類定義的屬性來修改取值,當(dāng)然不是直接修改這個類的配置,而是spring-boot應(yīng)用中對應(yīng)的配置文件:src/main/resources/appliperties.定義自動加載類定義src/resources/META-INF/spring.factories文件中的自動加載類,其目的是讓springboot更具文中中所指定的自動化配置類來自動初始化相關(guān)的Bean,Component或Service,它的內(nèi)容如下:在RocketMQAutoConfiguration類的具體實現(xiàn)中,定義開放給用戶直接使用的Bean對象.包括:lRocketMQProperties加載應(yīng)用屬性配置文件的處理類;lRocketMQTemplate發(fā)送端用戶發(fā)送消息的發(fā)送模板類;lListenerContainerConfiguration容器Bean負(fù)責(zé)發(fā)現(xiàn)和注冊消費端消費實現(xiàn)接口RocketMQListener泛化接口。最后具體的RocketMQ相關(guān)的封裝。在發(fā)送端(producer)和消費端(consumer)客戶端分別進行封裝,在當(dāng)前的實現(xiàn)版本提供了對SpringMessaging接口的兼容方式。普通發(fā)送端發(fā)送端的代碼封裝在RocketMQTemplatePOJO中,下圖是發(fā)送端的相關(guān)代碼的調(diào)用關(guān)系圖:為了與SpringMessaging的發(fā)送模板兼容,在RocketMQTemplate集成了AbstractMessageSendingTemplate抽象類,來支持相關(guān)的消息轉(zhuǎn)換和發(fā)送方法,這些方法最終會代理給doSend()方法;doSend()以及RocoketMQ所特有的一些方法如異步,單向和順序等方法直接添加到RoketMQTempalte中,這些方法直接代理調(diào)用到RocketMQ的ProducerAPI來進行消息的發(fā)送。事務(wù)消息發(fā)送端對于事務(wù)消息的處理,在消息發(fā)送端進行了部分的擴展,參考下圖的調(diào)用關(guān)系類圖:RocketMQTemplate里加入了一個發(fā)送事務(wù)消息的方法sendMessageInTransaction(),并且最終這個方法會代理到RocketMQ的TransactionProducer進行調(diào)用,在這個Producer上會注冊其關(guān)聯(lián)的TransactionListener實現(xiàn)類,以便在發(fā)送消息后能夠?qū)ransactionListener里的方法實現(xiàn)進行調(diào)用。在消費端Spring-Boot應(yīng)用啟動后,會掃描所有包含@RocketMQMessageListener注解的類(這些類需要集成RocketMQListener接口,并實現(xiàn)onMessage()方法),這個Listener會一對一的被放置到DefaultRocketMQListenerContainer容器對象中,容器對象會根據(jù)消費的方式(并發(fā)或順序),將RocketMQListener封裝到具體的RocketMQ內(nèi)部的并發(fā)或者順序接口實現(xiàn)。在容器中創(chuàng)建RocketMQConsumer對象,啟動并監(jiān)聽定制的Topic消息,如果有消費消息,則回調(diào)到Listener的onMessage()方法。上面的一章介紹了RocketMQ在spring-boot-starter方式的實現(xiàn),這里通過一個最簡單的消息發(fā)送和消費的例子來介紹如何使這個rocketmq-spring-boot-starter。啟動NameServer和Broker要驗證RocketMQ的Spring-Boot客戶端,首先要確保RocketMQ服務(wù)正確的下載并啟動。可以參考RocketMQ主站的快速開始來進行操作。確保啟動NameServer和Broker已經(jīng)正確啟動。創(chuàng)建實例中所需要的Topics在執(zhí)行啟動命令的目錄下執(zhí)行下面的命令行操作:目前的spring-boot-starter依賴還沒有提交的Maven的中心庫,用戶使用前需要自行下載git源碼,然后執(zhí)行mvncleaninstall安裝到本地倉庫。gitclone/apache/rocketmq-externals.gitcdrocketmq-spring-boot-startermvncleaninstall用戶如果使用它,需要在消息的發(fā)布和消費客戶端的maven配置文件pom.xml中添加如下的依賴:屬性spring-boot-starter-rocketmq-version的取值為:1.0.0-SNAPSHOT,這與上一步驟中執(zhí)行安裝到本地倉庫的版本一致。消息發(fā)送端的代碼發(fā)送端的配置文件perties:發(fā)送端的Java代碼:消息消費端代碼消費端的配置文件perties:消費端的Java代碼:這里只是簡單的介紹了使用spring-boot來編寫最基本的消息發(fā)送和接收的代碼,如果需要了解更多的調(diào)用方式,如:異步發(fā)送,對象消息體,指定tag標(biāo)簽以及指定事務(wù)消息,請參看github的說明文檔和詳細(xì)的代碼。我們后續(xù)還會對這些高級功能進行陸續(xù)的介紹。方法二:SpringCloudStream體系及原理介紹:spring-cloud-stream-binder-rocektmqPhotobyMedBadrChemmaouionUnsplashSpringCloudStream在SpringCloud體系內(nèi)用于構(gòu)建高度可擴展的基于事件驅(qū)動的微服務(wù),其目的是為了簡化消息在SpringCloud應(yīng)用程序中的開發(fā)。SpringCloudStream(后面以SCS代替SpringCloudStream)本身內(nèi)容很多,而且它還有很多外部的依賴,想要熟悉SCS,必須要先了解SpringMessaging和SpringIntegration這兩個項目,接下來,文章將從圍繞以下三點進行展開:l什么是SpringMessaging?l什么是SpringIntegration?l什么是SCS體系及其原理?SpringMessaging是SpringFramework中的一個模塊,其作用就是統(tǒng)一消息的編程模型。l比如消息Messaging對應(yīng)的模型就包括一個消息體Payload和消息頭Header:}l消息通道MessageChannel用于接收消息,調(diào)用send方法可以將消息發(fā)送至該消息通道中:}}消息通道里的消息如何被消費呢?l由消息通道的子接口可訂閱的消息通道SubscribableChannel實現(xiàn),被MessageHandler消息處理器所訂閱:}l由MessageHandler真正地消費/處理消息:}SpringMessaging內(nèi)部在消息模型的基礎(chǔ)上衍生出了其它的一些功能,如:1.消息接收參數(shù)及返回值處理:消息接收參數(shù)處理器HandlerMethodArgumentResolver配合@Header,@Payload等注解使用;消息接收后的返回值處理器HandlerMethodReturnValueHandler配合@SendTo注解使用;2.消息體內(nèi)容轉(zhuǎn)換器MessageConverter;3.統(tǒng)一抽象的消息發(fā)送模板AbstractMessageSendingTemplate;4.消息通道攔截器ChannelInterceptor;SpringIntegration提供了Spring編程模型的擴展用來支持企業(yè)集成模式(EnterpriseIntegrationPatterns),是對SpringMessaging的擴展。它提出了不少新的概念,包括消息路由MessageRoute、消息分發(fā)MessageDispatcher、消息過濾Filter、消息轉(zhuǎn)換Transformer、消息聚合Aggregator、消息分割Splitter等等。同時還提供了MessageChannel和MessageHandler的實現(xiàn),分別包括DirectChannel、ExecutorChannel、PublishSubscribeChannel和MessageFilter、ServiceActivatingHandler、MethodInvokingSplitter等內(nèi)容。這里為大家介紹幾種消息的處理方式:l消息的分割:l消息的聚合:l消息的過濾:l消息的分發(fā):接下來,我們以一個最簡單的例子來嘗試一下SpringIntegration:這段代碼解釋為:1.構(gòu)造一個可訂閱的消息通道m(xù)essageChannel;2.使用MessageHandler去消費這個消息通道里的消息;3.發(fā)送一條消息到這個消息通道,消息最終被消息通道里的MessageHandler所消費。最后控制臺打印出:receive:msgfromalibaba;DirectChannel內(nèi)部有個UnicastingDispatcher類型的消息分發(fā)器,會分發(fā)到對應(yīng)的消息通道MessageChannel中,從名字也可以看出來,UnicastingDispatcher是個單播的分發(fā)器,只能選擇一個消息通道。那么如何選擇呢?內(nèi)部提供了LoadBalancingStrategy負(fù)載均衡策略,默認(rèn)只有輪詢的實現(xiàn),可以進行擴展。我們對上段代碼做一點修改,使用多個MessageHandler去處理消息:由于DirectChannel內(nèi)部的消息分發(fā)器是UnicastingDispatcher單播的方式,并且采用輪詢的負(fù)載均衡策略,所以這里兩次的消費分別對應(yīng)這兩個MessageHandler。控制臺打印出:既然存在單播的消息分發(fā)器UnicastingDispatcher,必然也會存在廣播的消息分發(fā)器,那就是BroadcastingDispatcher,它被PublishSubscribeChannel這個消息通道所使用。廣播消息分發(fā)器會把消息分發(fā)給所有的MessageHandler:發(fā)送兩個消息,都被所有的MessageHandler所消費??刂婆_打?。篠CS與各模塊之間的關(guān)系是:lSCS在SpringIntegration的基礎(chǔ)上進行了封裝,提出了Binder,Binding,@EnableBinding,@StreamListener等概念;lSCS與SpringBootActuator整合,提供了/bindings,/channelsendpoint;lSCS與SpringBootExternalizedConfiguration整合,提供了BindingProperties,BinderProperties等外部化配置類;lSCS增強了消息發(fā)送失敗的和消費失敗情況下的處理邏輯等功能;lSCS是SpringIntegration的加強,同時與SpringBoot體系進行了融合,也是SpringCloudBus的基礎(chǔ)。它屏蔽了底層消息中間件的實現(xiàn)細(xì)節(jié),希望以統(tǒng)一的一套API來進行消息的發(fā)送/消費,底層消息中間件的實現(xiàn)細(xì)節(jié)由各消息中間件的Binder完成。Binder是提供與外部消息中間件集成的組件,為構(gòu)造Binding提供了2個方法,分別是bindConsumer和bindProducer,它們分別用于構(gòu)造生產(chǎn)者和消費者。目前官方的實現(xiàn)有RabbitBinder和KafkaBinder,SpringCloudAlibaba內(nèi)部已經(jīng)實現(xiàn)了RocketMQBinder。從圖中可以看出,Binding是連接應(yīng)用程序跟消息中間件的橋梁,用于消息的消費和生產(chǎn)。我們來看一個最簡單的使用RocketMQBinder的例子,然后分析一下它的底層處理原理:l啟動類及消息的發(fā)送:}}} }消息的接收:}}這段代碼很簡單,沒有涉及到RocketMQ相關(guān)的代碼,消息的發(fā)送和接收都是基于SCS體系完成的。如果想切換成RabbitMQ或Kafka,只需修改配置文件即可,代碼無需修改。我們來分析下這段代碼的原理:1.@EnableBinding對應(yīng)的兩個接口屬性Source和Sink是SCS內(nèi)部提供的。SCS內(nèi)部會基于Source和Sink構(gòu)造BindableProxyFactory,且對應(yīng)的output和input方法返回的MessageChannel是DirectChannel。output和input方法修飾的注解對應(yīng)的value是配置文件中binding的name。}配置文件里bindings的name為output和input,對應(yīng)Source和Sink接口的方法上的注解里的value:2.構(gòu)造CommandLineRunner,程序啟動的時候會執(zhí)行CustomRunner的run方法。3.調(diào)用Source接口里的output方法獲取DirectChannel,并發(fā)送消息到這個消息通道中。這里跟之前SpringIntegration章節(jié)里的代碼一致。lSource里的output發(fā)送消息到DirectChannel消息通道之后會被AbstractMessageChannelBinder#SendingHandler這個MessageHandler處理,然后它會委托給AbstractMessageChannelBinder#createProducerMessageHandler創(chuàng)建的MessageHandler處理(該方法由不同的消息中間件實現(xiàn));l不同的消息中間件對應(yīng)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年經(jīng)濟學(xué)原理與應(yīng)用模擬題集
- 2026年音樂基礎(chǔ)知識與鑒賞能力自測題集
- 2026年人工智能算法基礎(chǔ)測試
- 2026年經(jīng)濟學(xué)基礎(chǔ)知識考試題集
- 2026年法律職業(yè)資格考試沖刺法條與案例分析題
- 2026年鄭州商貿(mào)旅游職業(yè)學(xué)院單招綜合素質(zhì)筆試參考題庫含詳細(xì)答案解析
- 2026年長春東方職業(yè)學(xué)院單招綜合素質(zhì)筆試參考題庫含詳細(xì)答案解析
- 2026年江西應(yīng)用工程職業(yè)學(xué)院單招職業(yè)技能考試備考題庫含詳細(xì)答案解析
- 2026年安徽綠海商務(wù)職業(yè)學(xué)院單招綜合素質(zhì)考試備考試題含詳細(xì)答案解析
- 2026年南京特殊教育師范學(xué)院單招綜合素質(zhì)考試模擬試題含詳細(xì)答案解析
- 新工會考試試題題庫工會考試試題題庫及答案解析
- 企業(yè)用車制度規(guī)范標(biāo)準(zhǔn)
- 2025-2030中國道路標(biāo)志漆市場運營態(tài)勢分析與全面深度解析研究報告
- 電力網(wǎng)絡(luò)安全培訓(xùn)教學(xué)課件
- 網(wǎng)絡(luò)布線施工技術(shù)要求
- 上海市徐匯區(qū)上海中學(xué)2025-2026學(xué)年高三上學(xué)期期中考試英語試題(含答案)
- 黑布林英語漁夫和他的靈魂
- 初三畢業(yè)班寒假家長會課件
- 電站組件清洗措施及方案
- 冀教版五年級英語下冊全冊同步練習(xí)一課一練
- 城鎮(zhèn)土地估價規(guī)程
評論
0/150
提交評論