遇到了消息堆積,但是問題不大
這一篇我們要說的話題是消息的堆積處理,其實這個話題還是挺大的,因為消息堆積還是真的很令人頭疼的,當(dāng)堆積的量很大的時候,這真的是個很暴躁的問題,不過這時候真考驗大家冷靜的處理問題的能力了
我們一起來分析分析有關(guān)問題吧
大量的消息堆積在MQ中幾個小時還沒解決怎么辦呢
一般這種比較著急的問題,最好的辦法就是臨時擴容,用更快的速度來消費數(shù)據(jù)
? ? ?1、臨時建立一個新的Topic,然后調(diào)整queue的數(shù)量為原來的10倍或者20倍,根據(jù)堆積情況來決定
? ? ?2、然后寫一個臨時分發(fā)消息的consumer程序,這個程序部署上去消費積壓的消息,消費的就是剛剛新建的Topic,消費之后不做耗時的處理,只需要直接均勻的輪詢將這些消息輪詢的寫入到臨時創(chuàng)建的queue里面即可
? ? ?3、然后增加相應(yīng)倍數(shù)的機器來部署真正的consumer消費,注意這里的Topic,然后讓這些consumer去真正的消費這些臨時的queue里面的消息
不知道大家明白沒有,很簡單的道理,我給大家舉個形象的例子
一個topic堵住了,新建一個topic去進(jìn)行分流,臨時將queue資源和consumer資源擴大10倍,將消息平均分配到這些新增的queue資源和consumer資源上,以正常10倍的速度來消費消息,等到這些堆積的消息消費完了,便可以恢復(fù)到原來的部署架構(gòu)
這種只是用于臨時解決一些異常情況導(dǎo)致的消息堆積的處理,如果消息經(jīng)常出現(xiàn)堵塞的情況,那該考慮一下徹底增強系統(tǒng)的部署架構(gòu)了
消息設(shè)置了過期時間,過期就丟了怎么辦呢
在rabbitmq中,可以設(shè)置過期時間TTL,和Redis的過期時間一樣,如果消息在queue中積壓超過一定時間就會被rabbitmq清理掉,這個數(shù)據(jù)就沒了
這樣可能會造成大量的數(shù)據(jù)丟失
這種情況下上面的解決方案就不太合適了,可以采取批量重導(dǎo)的方案來解決,在系統(tǒng)流量比較低的時候,用程序去查詢丟失的這部分?jǐn)?shù)據(jù),然后將消息重新發(fā)送到MQ中,把丟失的數(shù)據(jù)重新補回來
這也算是一種補償任務(wù)吧,補償任務(wù)一般是用于對定時跑批的一種補償
分析下RocketMQ中的消息堆積原因
消息的堆積歸根到底就是生產(chǎn)者生產(chǎn)消息的速度和消費者消費的速度不匹配導(dǎo)致的,輸入的和消費的速度不統(tǒng)一
或許是突然搞了一波促銷,系統(tǒng)業(yè)務(wù)量暴增,導(dǎo)致生產(chǎn)者發(fā)消息暴增,消費速度跟不上
也有可能是消費方出現(xiàn)失敗的情況,瘋狂重試,也或者就是消費方的消費能力太低了
RocketMQ是按照隊列進(jìn)行消息負(fù)載的,如果consumer中的一臺機器由于硬件各方面原因?qū)е略摍C器上的消息隊列不能及時處理,就會造成整個消息隊列的堆積
RocketMQ分為發(fā)布方和訂閱方,雙方都有負(fù)載均衡策略,默認(rèn)都是采用平均分配,producer消息以輪詢方式發(fā)送到消息隊列queue中,broker將這些的queue再平均分配到屬于同一個group id的訂閱方集群
.如果消費者consumer機器數(shù)量和消息隊列相等,則消息隊列平均分配到每一個consumer上 如果consumer數(shù)量大于消息隊列數(shù)量,則超出消息隊列數(shù)量的機器沒有可以處理的消息隊列 若消息隊列數(shù)量不是consumer的整數(shù)倍,則部分consumer會承擔(dān)跟多的消息隊列的消費任務(wù)
那說一下解決思路吧
RocketMQ中消費完的消息去了哪里呢
CommitLog文件什么時候進(jìn)行清除
消息文件過期(默認(rèn)72小時),且到達(dá)清理時點(默認(rèn)是凌晨4點),刪除過期文件。 消息文件過期(默認(rèn)72小時),且磁盤空間達(dá)到了水位線(默認(rèn)75%),刪除過期文件。 磁盤已經(jīng)達(dá)到必須釋放的上限(85%水位線)的時候,則開始批量清理文件(無論是否過期),直到空間充足。
為什么這么設(shè)計呢
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號
好文章,我在看??
