SpringBoot管理RabbitMQ中的Channel詳解
Channel是什么
RabbitMQ是AMQP0-9-1協(xié)議的實現(xiàn),先來看看AMQP0-9-1協(xié)議中對通道Channel的闡述。
有些應(yīng)用程序需要與broker建立多個連接。但是,保持多個TCP連接同時打開是不可取的,因為這樣做會消耗系統(tǒng)資源,使配置防火墻更加困難。AMQP0-9-1的Connection可以多路復(fù)用,Channel可以被認為是“共享一個TCP連接的輕量級連接”。
客戶端執(zhí)行的每個協(xié)議操作都發(fā)生在一個channel上。在特定channel上的通信與在另一個channel上的通信完全獨立,因此每個協(xié)議方法也都帶有信道ID(a.k.a)。一個整數(shù),代理和客戶端都使用它來確定該方法用于哪個通道。
channel僅存在于connection的上下文中,而不會單獨存在。當(dāng)channel關(guān)閉時,其上的所有channel也會關(guān)閉。
對于使用多個線程/進程進行處理的應(yīng)用程序,為每個線程/進程打開一個新channel而不在它們之間共享channel是很常見的。
在普通的JAVAEE項目中,經(jīng)常采用1個進程-1個connection-1個channel。
但是這在JAVAWEB場景中實不可取的。
一個web項目僅有1個進程,會有非常多的線程,每個線程都創(chuàng)建一個connection是不可取的。
在AMQP-0-9-1協(xié)議中推薦了使用每個線程使用一個獨立的channel,這樣不同線程之間的channel相互獨立,并且公用同一個connection。
但是問題又來了,在并發(fā)情況下,web場景下,用戶的每一次http請求都是一個線程,難道這樣的每一個http請求都要對應(yīng)創(chuàng)建一個channel嗎?
Spring在集成RabbitMQ時對這個問題有了非常好的解決。
Spring如何管理Channel?
springboot使用了RabbitMQ中的IO多路復(fù)用的理念,并對這種方案在web場景下進行了優(yōu)化,盡可能的復(fù)用空閑中的channel。
boot默認使用 CachingConnectionFactory 對 Connection 和空閑 Channel 進行緩存。
看看Spring中的RabbitMQ是如何工作的:
Spring中對RabbitMQ的消息操作都是通過一個Template模板對象 RabbitTemplate ,該對象中封裝了對消息的接受和發(fā)送的各種重載方法。
消息的send都需要調(diào)用一個核心私有方法 doExcute() 。
管理RabbitMQ中的事務(wù)Channel
Spring也是通過 TransactionSupport 進行管理RabbitMQ中的事務(wù)Channel。
這一點和MyBatis的 SqlSessionTemplate 管理開啟事務(wù)的 SqlSession 的步驟相同。
這里不多贅述如果管理事務(wù)的channel
1.當(dāng)?shù)谝淮斡姓埱筮B接rabbitmq時,spring創(chuàng)建一個AMQP的connection,并使用CachingConnectionFactory將其封裝并緩存起來。
2.然后使用這個connection,創(chuàng)建channel,當(dāng)channel的任務(wù)執(zhí)行完成后(也就是邏輯close時,并非真正的關(guān)閉了channel,而是在內(nèi)存中給channel創(chuàng)建了一個標記。)
則使用 CachingConnectionFactory 的靜態(tài)子類 ChannelConnectionFactoryProxy 把這個channel緩存到一個空閑列表中。開啟了事務(wù)的channel存放在不同的列表中。
3.其他線程執(zhí)行任務(wù)時,CachingConnectionFactory中獲取connection,然后創(chuàng)建channel時,會去ChannelConnectionFactoryProxy的空閑列表中尋找哪些channel是open狀態(tài)。
然后將尋找到的一個channel移出列表,并使用這個channel執(zhí)行任務(wù)。(取出緩存中的channel這一過程是同步代碼塊, 開啟了事務(wù)的channel存放在不同的列表中。)
4.任務(wù)執(zhí)行完畢,將channel在緩存入空閑列表中。默認最多緩存25個channel
到此這篇關(guān)于SpringBoot管理RabbitMQ中的Channel詳解的文章就介紹到這了,更多相關(guān)SpringBoot管理Channel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java注解的Retention和RetentionPolicy實例分析
這篇文章主要介紹了Java注解的Retention和RetentionPolicy,結(jié)合實例形式分析了Java注解Retention和RetentionPolicy的基本功能及使用方法,需要的朋友可以參考下2019-09-09關(guān)于spring boot整合kafka+注解方式
這篇文章主要介紹了關(guān)于spring boot整合kafka+注解方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09spring?@Transactional注解中常用參數(shù)詳解
這篇文章主要介紹了spring?@Transactional注解中常用參數(shù)詳解,事物注解方式:?@Transactional,本文結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2024-02-02