背景:
線上環境,出了一起事故,初步定位是rabbitmq server。
通過抓包發現,是有多個應用使用同一台rabbitmq server。並且多個應用使用rabbitmq的方式也不一樣。發現有以下兩種方式:
1. 每次produce 一條消息,開閉channel一次
2. 每次produce 一條消息,開閉connection一次,開閉channel一次。
這種使用方法是我們懷疑的一個點,除此之外還有懷疑的點有:
1. rabbitmq cluster的配置問題
2. rabbitmq server的硬件問題(體現在磁盤的io_wait 升高,tcp連接數的上升)
3. rabbitmq 本身的問題?
4. 網絡抖動和網絡延遲?
因為可能性比較多,所以,做一次全面的評估和定位還是有必要的。
有些任務交給IT和運維去追蹤了。我這邊主要負責一下客戶端使用方式的評估
目標:
1. 確認使用兩種使用方法(見上文),是否會造成瓶頸?
2. 確認兩種使用方法,在什么情況下會出問題?是否會百分百可以重現?
從理論上,rabbitmq文檔,以及抓包數據來說:每條消息開關一次connection 必然是效率最低的。
試想一下,每條消息體,需要建立和關閉一條tcp連接,中間還要摻雜着AMQP的控制報文,多么的浪費資源!!!!
簡單的測評結果如下:
方法描述 | 高峰消息量 | 參數 | 備注 |
共用一個connection,每條消息開關一次channel。 | 2000msg/s | 1個線程,無消費者 | 使用本機Rabbitmq,本地java client |
每條消息開關一次connection | 200msg/s | 1個線程,無消費者 | 使用本機Rabbitmq,本地java client |
上面這個結果是一個簡單的測試結果。
在嘗試混合使用兩種模式訪問本地rabbitmq的時候,出現了一下問題。問題也很奇怪,有一個方法的進程啟動后,另外一種就會SocketTimeout。
后面只好在測試環境找了台Rabbitmq Server。
然后google了一把,原來有個jmeter-rabbitmq-plugin。太帥了。功能不全是自己要的,沒關系,改唄。代碼參見:https://github.com/lykm02/JMeter-Rabbit-AMQP 。(我更新了maven build 方式和一些jar version信息,在branch support_maven_xx 上)
放到jmeter中,就可以使用jmeter來壓了。
結論是:確實connection的使用方式 會影響到rabbitmq的內部,從而導致其他連接到同一rabbitmq的連接收到影響。
具體工作原理,因為涉及到rabbitmq的源碼,目前沒有深入研究。