Spring AMQP雜記之Spring實現簡述
上一篇主要介紹了AMQP的一些知識,接下來開始正式步入Spring AMQP。
首先介紹下Spring對於AMQP的抽象
Message:在AMQP中並沒有定義訊息的模型,Spring為了方便我們理解與使用,新增了Message介面,在構建訊息的時候Spring提供了builde API,MessageBuilder.xx.xx的形式使用起來很方便。
Exchange:這個介面和AMQP中定義的exchange基本相同,就不說了
Queue:同上。
Binding:一般叫他繫結關係,AMQP也有對其的抽象模型,只不過我認為他只不過相當於是附加在佇列與交換機上的屬性,所以在上篇關於AMQP的介紹中並沒有詳細說明。呃,其實spring對其的定義就是代表了佇列與交換機的繫結關係。。。
如何連線RabbitMQ
spring提供了ConnectionFactory介面,當我們使用的時候會使用它的實現類CachingConnectionFactory,看名字也知道就是基於快取的連線池,預設的池大小為25。Spring也提供了對於多個connectionFactory的支援介面例如SimpleRoutingConnectionFactory等。
我們使用SpringBoot進行測試,最小化的配置如下
如何向RabbitMQ傳送與接收訊息?
這裡先給出一個簡單的例子然後再具體講解。
如圖,我們提前宣告瞭一個名為hello的佇列,瀏覽器訪問/send時,可以看到控制檯列印了相應的時間資訊,即被@RabbitListener註解的方法被呼叫了。如果我們開啟RabbitMq的webUI,會發現名為hello的佇列中訊息數量由0變為1再變為0。注意,這裡我們並沒有宣告Exchange,MQ會為我們將佇列繫結到預設的Exchange。
接下來就詳細的說一下這個例子。對於操作RabbitMQ,Spring提供了 RabbitTemplate(對於batch操作,相應的是BatchingRabbitTemplate,在1.6版本以後,spring提供了非同步的Template--AsyncRabbitTemplate)。我們使用它來傳送與接收訊息。當傳送完訊息的時候如何知道本次操作的成功或者失敗呢?預設情況下不能被路由的訊息將會被丟棄,這會導致訊息丟失,不能保證訊息可靠性(訊息可靠性請參照上一篇AMQP介紹中的推薦)。釋出確認機制是保證訊息可靠性的第一步,釋出確認保證我們知道訊息是否成功到達佇列中,返回ack則代表成功,nack則代表失敗。要使用這個特性,我們需要將RabbitTemplate的mandatory屬性和ConnectionFactory的publisherConfirms屬性都設為true。這時我們可以在RabbitTemplate上設定setReturnCallback監聽來接收MQ伺服器返回的狀態資訊了。對於訊息的確認,我們只需要設定RabbitTemplate.ConfirmCallback的回撥方法即可。
當我們每次傳送請求時,都會列印相應的ack,其中correlationData是生產者在傳送資料時可以攜帶的相關資訊。這裡有個問題需要注意一下,RabbitTemplate只允許設定一個callback方法,這時你可以將RabbitTemplate的bean設為單例然後設定回撥。
這樣的缺點是所有使用這個template的地方都會使用這個回撥,那麼當我們想要為不同的操作定製callBack該怎麼做?如果直接在別的地方繼續設定會報"Only one ConfirmCallback is supported by each RabbitTemplate"異常,這時候我們就需要將RabbitTemplate的作用域設為@Scope,這樣每個bean都是一個新的。難道這樣就可以了麼?我們的service類一般都是單例的,這意味著當service類生成後,注入的RabbitTemplate就已經不變了,這個就是Single域的bean中注入Scope域bean的問題。一種解決方法是實現ApplicationAware介面注入ApplicationContext,每次使用RabbitTemplate時呼叫其getBean方法。一個更好的解決方案是使用spring提供的lookup方法。
spring會幫我們代理lookup註解的方法,每次呼叫都會返回一個全新的bean。但其實平常使用一般都會將傳送方單獨抽取出來實現回撥介面,不會涉及上面的問題,一般都如下配置,注意將template配置成scope即可。
RabbitTemplate可以新增訊息轉換器,作用就類似於mvc中配置的@ResponseBody訊息轉換器。
具體如何傳送與接收訊息感覺不用咋說了。。。就send,receive(x,x,x)這個用IDE看一下方法doc就知道咋用了。receive為拉模式,很少使用,關於接收方法我們更常使用的是非同步接收,即推模式,一般使用@RabbitListener 實現
當hello佇列中有訊息時,方法會自動呼叫。
像我們平常做web開發,前端想要接受來自後臺的訊息無非倆個方法,前臺請求和後臺推送,前臺輪詢一般就是ajax定時器,推送一般使用WebSocket實現,MQ同樣有兩種模式:輪詢請求佇列看是否有訊息即拉模式,佇列中有訊息即對消費者進行通知即推模式。
對於拉模式,Spring提供了receive,receiveAndConvert,和receiveAndReply方法。接收並回復的方法很有用,比如訂單系統,下單訊息被MQ處理完後再返回訊息給其他佇列,告訴她這個訂單已經完成,可以進行付費操作了。接收並回復呼叫template.receiveAndReply實現自己的接收回撥。對於推模式,專案中基本上使用@RabbitListener註解完成,該註解結合@SendTo註解完成receiveAndReply功能,若沒有sendto,這個方法是不允許有返回值的。對於異常情況,配置@RabbitListener的errorHandler和returnExceptions即可。關於@RabbitListener註解的具體使用其實也挺複雜的,推薦直接看文件。使用監聽器的過程中訊息是預設經過訊息轉換器的,可以手動為其設定訊息轉換器。關於RabbitMQ LIstener的配置可以使用Config方式或者SpringBoot的配置檔案方式。
上面只是官方文件的一部分,其實除了Listener大部分Config方式的配置都可以用配置檔案方式替代。
宣告佇列與交換機:分為xml方式和Java Config方式(懶得寫了,這個基本官網就是複製貼上)
配置Broker:Spring對其的抽象為RabbitAdmin,也是官網。。
延時佇列實現:設定交換機延時屬性為true,通過convertAndSend中的MessagePostProcessor實現傳送延時訊息,這個方法需要安裝延時交換機這樣的一個外掛(也可以通過死信佇列實現)
好了。今天就先寫這麼多,因為實在是寫的太亂了,以後有時間整理一下。。。
相關文章
- Spring MVC 簡述SpringMVC
- spring-boot-starter-amqp踩坑記SpringbootMQ
- Spring5.0原始碼學習系列之Spring AOP簡述Spring原始碼
- Spring AMQP:RabbitTemplate SimpleMessageListenerContainerSpringMQAI
- 簡易版的Spring框架之IOC簡單實現Spring框架
- Spring AMQP 實戰 - 整合 RabbitMQ 傳送郵件SpringMQ
- Spring AMQP 實戰 – 整合 RabbitMQ 傳送郵件SpringMQ
- 簡述Spring技術內幕Spring
- Spring Boot啟動流程簡述Spring Boot
- Spring之AOP實現Spring
- Spring Security系列之實現簡訊登入(十)Spring
- 簡易版的 Spring 之如何實現 Constructor 注入SpringStruct
- Spring綜述Spring
- Spring框架系列(12) - Spring AOP實現原理詳解之JDK代理實現Spring框架JDK
- Spring Bean 綜述SpringBean
- Spring-1-AOP概念簡述-程式碼演示Spring
- 簡單實現類似Spring的Aop原理實現Spring
- Spring框架系列(9) - Spring AOP實現原理詳解之AOP切面的實現Spring框架
- Spring框架系列(11) - Spring AOP實現原理詳解之Cglib代理實現Spring框架CGLib
- 自己簡單實現Spring的IOC原理Spring
- Spring Security原始碼分析五:Spring Security實現簡訊登入Spring原始碼
- docker環境下的RabbitMQ部署,Spring AMQP使用DockerMQSpring
- spring原始碼學習筆記之容器的基本實現(一)Spring原始碼筆記
- Spring Data JPA + QueryDSL實現CRUD和複雜查詢案例Spring
- Spring原始碼之容器的基本實現Spring原始碼
- Spring AOP 實現業務日誌記錄Spring
- Spring 架構的簡單模擬實現Spring架構
- 簡述RPC原理實現RPC
- 簡易版的Spring框架之AOP簡單實現(對我來說不簡單啊)Spring框架
- Spring——AOP實現Spring
- Spring boot學習(六)Spring boot實現AOP記錄操作日誌Spring Boot
- Spring筆記(9) - IOC實現方式詳解Spring筆記
- Spring Cloud Gateway之RouteLocator簡介SpringCloudGateway
- Spring入門筆記簡要Spring筆記
- 如何實現一個簡易版的 Spring - 如何實現 AOP(中)Spring
- 如何實現一個簡易版的 Spring - 如何實現 AOP(上)Spring
- 如何實現一個簡易版的 Spring - 如何實現 Setter 注入Spring
- 簡述用React實現Table元件React元件