Spring RabbitMQ Channel理解

概述


AMQP協議中,有channel的概念,在RabbitMq中,channel表示邏輯連接或者叫虛擬連接,是棣屬於TCP連接的。一個TCP連接裏可以創建多個channel,在Rabbit MQ裏,消息的發送和接收都是基於channel的。
collection和channel的關係

有了TCP連接後,還需要channel的原因如下:

  • 創建和銷燬TCP連接很耗時;
  • 打開太多TCP連接,耗操作系統資源,併發量大到一定程度,系統的吞吐量會降低;
  • 使用一個collectionchannel的方式,可以提升連接的利用率。

因此採用多個channel多路複用一個TCP連接的方式才比較合理。


channel線程不安全


channel不是線程安全的,線程併發的去訪問同一個channel會出問題。這裏有幾種處理方式:

  1. 全局公用一個channel且使用全局鎖,讓操作channel排隊.這種明顯性能是不行的;
  2. 一個線程對應創建一個新的channel,但是要處理好一個連接能支撐的最大channel數量;
  3. 一個線程對應一個channel,但是是從channel池子拿的,不是每次都創建新的.一旦一個線程完成了一個channel的使用,它將返回到池中,從而使該channel可用於另一個線程。

量不大的話,使用第二種方式就可以了。量大的話,建議使用第三種方式,畢竟創建和銷燬channel也是耗時耗資源的.在spring amqp中,提供了一個緩存channel的方案。可以在創建CachingConnectionFactory時指定緩存的模式。

connectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CHANNEL);
connectionFactory.setChannelCacheSize(25);

上面的兩行代碼,表示channel共用唯一的一個連接,且緩存了25個channel,注意這裏的25個並不是說,這個連接裏只能最多創建25個channel,而是說最多緩存25個channel。舉個例子,假設併發發送100條消息,在CachingConnectionFactory.CacheMode.CHANNEL模式下,瞬間會創建100個channel的,然後往緩存裏放25個channel,當流量下去了,剛剛創建的多餘的channel會自動關閉掉的,緩存裏只保留25個。

使用這種方式的話,要注意緩存的channel數量,不能太小,不然流量一大,仍然會造成頻繁關閉channel的情況。當然我們也不能說有多少併發,就創建多少個channel,還是要限制一下,這個時候可以使用:

connectionFactory.setChannelCheckoutTimeout(1000);

ChannelCheckoutTimeout的值大於0的時候,ChannelCacheSize的值就是最大的channel數量了,一旦從緩存中獲取不到channel,等待ChannelCheckoutTimeout毫秒後,如果還是獲取不到的,就會拋AmqpTimeoutException了。

我們也可以自己實現channel pool,但是不太建議怎麼做,畢竟spring amqp還是相當成熟的,直接使用就可以了。


CacheMode.CHANNEL模式性能


如上文所述,採用了CacheMode.CHANNEL的模式的話,就是一線程一channel形式,且這些channel共享了同一個連接,也即是共享同一個socket。當併發量一大的時候,可能導致同一時刻,多個線程都想往這個socket上寫數據。爲了避免這種情況,只能加鎖,讓拿不到鎖的線程block住。在老外寫的Using spring-rabbit under high throughput一文中,也提到了這點,並做了壓力測試,併發10個線程發送1000000條消息,結果線程被block住了,如下圖:
在這裏插入圖片描述
作者也提到,當流量很大的時候,使用CacheMode.CONNECTION的模式,可以提高發送效率。關於這兩種模式的性能問題,也可以看一下在stackoverflow的討論,Spring CachingConnectionFactory limiting channels & causing Thread Blocking;


channel的監控


RabbitMQ Admin UI提供了一個監控channel的界面,我們主要關注兩點:

  • channel有沒有可能泄露,打開了channel,卻沒有關閉channel;
  • 打開channel和關閉channel的速率。

如果通道打開操作的速率始終高於通道關閉操作的速率,那就可能發生channel泄露了。如下圖:
在這裏插入圖片描述

如果打開和關閉channel的速率都很高,也值得觀察一下。因爲可能是沒有緩存channel了。當流量繼續增大的時候,可能會出現吞吐量上不去的情況,如下圖:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章