ActiveMQ集群消息轉(zhuǎn)發(fā)問題整理(solved)

在我之前發(fā)的兩篇問題整理中,梳理了一下ActiveMQ集群轉(zhuǎn)發(fā)問題的分析過程:
ActiveMQ集群消息轉(zhuǎn)發(fā)問題整理(一)
ActiveMQ集群消息轉(zhuǎn)發(fā)問題整理(二)

這里簡要介紹一下問題的發(fā)現(xiàn)和分析過程:

問題發(fā)現(xiàn)

環(huán)境中 8000+ 個 Client 連接8臺MQ甸昏,使用 non-durable 的方式訂閱各自C類網(wǎng)段的TOPIC顽分,例如 192.168.0.1 訂閱 TOPIC:VLAN.192.168.0 。環(huán)境中大約有160+個C類網(wǎng)段施蜜,所以大約有160個TOPIC卒蘸。
下發(fā)針對全量 Client 的任務的時候,常常發(fā)現(xiàn)有個別 Client 收不到任務。由于我之前做了個任務流插件缸沃,可以跟蹤到任務是否到達MQ恰起,見(ActiveMQ插件開發(fā)實例-任務日志)表現(xiàn)為任務到達了生產(chǎn)者所在的MQ,但是沒有被轉(zhuǎn)發(fā)到Client所在的MQ趾牧。

問題分析

一检盼、進一步現(xiàn)象
根據(jù)現(xiàn)象進一步測試發(fā)現(xiàn)如下的現(xiàn)象:

  1. 假設 Client_A連接MQ_A,消費TOPIC_A翘单。消息下發(fā)時吨枉,出現(xiàn)Client_A接收不到消息的情況。
  2. Client_A連接的MQ_A上只有這個Client_A一個消費者消費TOPIC_A上的消息哄芜。
  3. 查看TOPIC的訂閱者信息貌亭,除了Client_A外,還可能出現(xiàn)該MQ轉(zhuǎn)發(fā)到其他MQ上的虛擬消費者认臊,表示發(fā)到這個TOPIC的消息需要被轉(zhuǎn)發(fā)給其他MQ
  4. 集群內(nèi)其他所有MQ上的TOPIC_A上查看訂閱者圃庭,均未出現(xiàn)類似的虛擬消費者,表示消息不會被轉(zhuǎn)發(fā)到MQ_A美尸,所以Client_A無法收到消息冤议。
  5. 重啟Client,Client會自動飄到集群內(nèi)其他的MQ上师坎,此時可以正常消費恕酸。
  6. 指定MQ_A要求Client_A重啟后連接到MQ_A,也可以正常消費胯陋。

這些現(xiàn)象表明這是一個偶發(fā)的問題蕊温,所以可能需要進一步深入到源碼級別查找一下問題原因。

二遏乔、源碼分析
首先要明確一下MQ集群中的轉(zhuǎn)發(fā)機制是怎樣的义矛。由于是 non-durable 的topic,使用的應該是 DemandForwardBridge 的方式盟萨。該方式的原理根據(jù)AMQ官網(wǎng)上的介紹凉翻,是通過集群中的 MQ 訂閱集群中其他 MQ 的 advisory topic 實現(xiàn)的。舉個例子:

  1. Broker A和Broker B為集群中兩臺MQ捻激。
  2. A,B啟動時制轰,便通過靜態(tài)配置對方IP的方式得知集群中有另一個MQ存在,所以建立了連接對方的通道胞谭,并訂閱了對方的 ActiveMQ.Advisory.Consumer.> 的topic垃杖。
  3. 當 A 上連接了一個消費者,訂閱topic1時丈屹,A便會往自己的 ActiveMQ.Advisory.Consumer.Topic.topic1 發(fā)送一條帶上了消費者信息(ConsumerInfo) 的消息调俘。
  4. B接收到這條 Advisory 消息以后,知道了A有一個消費者要消費topic1,就會建立一個專門的訂閱通道(DemandSubscription)彩库。
  5. 當 B 上收到生產(chǎn)者往 topic1 發(fā)送的消息時肤无,會同時往 A 上轉(zhuǎn)發(fā)一份。A收到以后再發(fā)送給自己的消費者侧巨。

從訂閱 Advisory Topic 到消息轉(zhuǎn)發(fā)舅锄,所有的動作都在 activemq-broker 的 org.apache.activemq.network.DemandForwardBridgeSupport 類中實現(xiàn)。其中 serviceRemoteConsumerAdvisory() 方法用于處理接收到的Advisory 消息司忱,該方法調(diào)用了 addConsumerInfo() 方法皇忿,用于建立 DemanSubscription 。

于是我修改了 DemandForwardBridgeSupport 和 AdvisoryBroker(用于發(fā)送 Advisory 消息)這兩個類坦仍,增加了一些日志來分析異常的場景下到底是哪一環(huán)節(jié)出了問題鳍烁。

##########正常的日志##########
1. Client-1 連接到 Broker A,Broker A 添加消費者繁扎,消費者ID為 Client-1
2. Broker A 發(fā)送 Advisory 消息幔荒,廣播Client-1的ConsumerInfo
3. Broker B 收到 Client-1的 Advisory 消息,添加消費者梳玫,消費者ID為 Broker B->Broker A
4. Broker B 發(fā)送 Advisory 消息爹梁,廣播 Broker B->Broker A 的ConsumerInfo
5. Broker C 收到 Client-1的 Advisory 消息,添加消費者提澎,消費者ID為 Broker C->Broker A
6. Broker C 發(fā)送 Advisory 消息姚垃,廣播 Broker C->Broker A 的ConsumerInfo
7. Broker C 收到 Broker B->Broker A 的 Advisory 消息,由于 networkTTL=1 的設置盼忌,不添加消費者积糯。
8. Broker B 收到 Broker C->Broker A 的 Advisory 消息,由于 networkTTL=1 的設置谦纱,不添加消費者嘉栓。
9. Broker A 收到 Broker B->Broker A 的 Advisory 消息缭付,由于 networkTTL=1 的設置究履,不添加消費者亡笑。
10. Broker A 收到 Broker C->Broker A 的 Advisory 消息,由于 networkTTL=1 的設置祠乃,不添加消費者窘游。

##########異常的日志##########
1. Client-1 連接到 Broker A,Broker A 添加消費者跳纳,消費者ID為 Client-1
2. Broker A 發(fā)送 Advisory 消息,廣播Client-1的ConsumerInfo
3. Broker B 收到 Client-1的 Advisory 消息贪嫂,添加消費者寺庄,消費者ID為 Broker B->Broker A
4. Broker B 發(fā)送 Advisory 消息,廣播 Broker B->Broker A 的ConsumerInfo
5. Broker C 收到 Broker B->Broker A 的 Advisory 消息,由于 networkTTL=1 的設置斗塘,不添加消費者赢织。
6. Broker A 收到 Broker B->Broker A 的 Advisory 消息,由于 networkTTL=1 的設置馍盟,不添加消費者于置。

可以看到,Broker C 異常場景下沒有接收到 Broker A 的消息贞岭。也就是說八毯,消息從 Broker A 中發(fā)出,但是在 Broker C 消費時丟失了瞄桨。

異常場景只在大量 Client 同時嘗試連接话速,且出現(xiàn)問題的 Topic 網(wǎng)段中 Client 數(shù)量較少。

問題解決

我嘗試了多種方法芯侥,始終無法解決Advisory消息沒收到的問題泊交,于是我在默認 Advisory 消息會丟的情況下設計了幾種解決方法:

  1. 設置 networkTTL=2
  2. 嘗試本地接收 Advisory 消息并存在內(nèi)存中,等到服務器不忙的時候直接再發(fā)一次柱查。
    前一種方法對一個互相連接的集群來說廓俭,有極大的網(wǎng)絡負擔;而后一個方法邏輯比較復雜唉工,比較難判斷 Advisory 消息什么時候該發(fā)研乒。一怒之下我提了個 AMQ 嚴重BUG到JIRA上。一開始有人建議我升級到5.15以上的版本再試試酵紫,于是我試了下告嘲,問題仍然存在。

在我把我分析問題的流程寫到JIRA上以后奖地,有人回復我是我需要去掉AMQ的一個默認配置橄唬。

          <policyEntry topic=">" >
                  <pendingMessageLimitStrategy>
                    <constantPendingMessageLimitStrategy limit="1000"/>
                  </pendingMessageLimitStrategy>
          </policyEntry>

pendingMessageLimitStrategy這個配置項用于處理 Slow Consumer,AMQ官方的解釋是這樣的(Slow Consumers

Slow Consumers can cause problems on non-durable topics since they can force the broker to keep old messages in RAM which once it fills up, forces the broker to slow down producers, causing the fast consumers to be slowed down. One option we could implement in the future is spooling to disk - but then spooling to disk could slow down the fast consumers too.

Currently we have a strategy that lets you configure the maximum number of matched messages the broker will keep around for a consumer in addition to its prefetch buffer. Once this maximum is reached, as new messages come in, older messages are discarded. This allows you to keep the RAM for current messages and keep sending messages to a slow consumer but to discard old messages.

也就是是說参歹,可配置一個 non-durable topic 的 consumer 可以讓MQ為其保存多少消息仰楚,由于 topic=">" 的寫法 ,Advisory的Topic也被包含在這個配置的使用范圍內(nèi)犬庇。所以僧界,當有大量 Client 連接上來時,MQ會發(fā)送大量的 Advisory Messages臭挽,如果集群中其他MQ的對 Advisory Messages沒有及時處理完捂襟,就會導致觸發(fā)這個機制,新的 Advisory 消息會持續(xù)把舊的 Advisory 消息頂出隊列(as new messages come in, older messages are discarded)欢峰。

綜上所述葬荷,如果場景中有多個MQ組成集群涨共,有大量的Client嘗試連接,就需要調(diào)整這個配置宠漩,避免出現(xiàn) advisory 消息被丟棄的情況举反。

Problem Solved.

山窮水復疑無路,柳暗花明又一村

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扒吁,一起剝皮案震驚了整個濱河市火鼻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雕崩,老刑警劉巖魁索,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異晨逝,居然都是意外死亡蛾默,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門捉貌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來支鸡,“玉大人,你說我怎么就攤上這事趁窃∧琳酰” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵醒陆,是天一觀的道長瀑构。 經(jīng)常有香客問我,道長刨摩,這世上最難降的妖魔是什么寺晌? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮澡刹,結(jié)果婚禮上呻征,老公的妹妹穿的比我還像新娘。我一直安慰自己罢浇,他們只是感情好陆赋,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嚷闭,像睡著了一般攒岛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胞锰,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天灾锯,我揣著相機與錄音,去河邊找鬼嗅榕。 笑死顺饮,一個胖子當著我的面吹牛色乾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播领突,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼案怯!你這毒婦竟也來了君旦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤嘲碱,失蹤者是張志新(化名)和其女友劉穎金砍,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體麦锯,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡恕稠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了扶欣。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹅巍。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖料祠,靈堂內(nèi)的尸體忽然破棺而出骆捧,到底是詐尸還是另有隱情,我是刑警寧澤髓绽,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布敛苇,位于F島的核電站,受9級特大地震影響顺呕,放射性物質(zhì)發(fā)生泄漏枫攀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一株茶、第九天 我趴在偏房一處隱蔽的房頂上張望来涨。 院中可真熱鬧,春花似錦忌卤、人聲如沸扫夜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笤闯。三九已至,卻和暖如春棍厂,著一層夾襖步出監(jiān)牢的瞬間颗味,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工牺弹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留浦马,地道東北人时呀。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像晶默,于是被迫代替她去往敵國和親谨娜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容