溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

RocketMQ broker busy的示例分析

發(fā)布時間:2021-12-17 14:18:08 來源:億速云 閱讀:201 作者:小新 欄目:大數(shù)據(jù)

這篇文章主要介紹RocketMQ broker busy的示例分析,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!

首先,broker busy 相關(guān)的日志關(guān)鍵字如下:

  • [REJECTREQUEST]system busy

  • too many requests and system thread pool busy

  • [PC_SYNCHRONIZED]broker busy

  • [PCBUSY_CLEAN_QUEUE]broker busy

  • [TIMEOUT_CLEAN_QUEUE]broker busy

本文先給出一張流程圖,展示上述5種 broker busy 分別會在消息發(fā)送的哪個階段拋出,以便大家能夠清晰的了解其發(fā)生的原因。

RocketMQ broker busy的示例分析  

 針對前4種 broker busy 出現(xiàn)的問題已經(jīng)在上篇文章中詳細(xì)介紹,主要是由于 Broker 在追加消息時持有的鎖時間超過了設(shè)置的1s,Broker 為了自我保護(hù),會拋出錯誤,客戶端會選擇其他 broker 服務(wù)器進(jìn)行重試。如果對不是金融級服務(wù),建議將 transientStorePoolEnable = true,可以有效避免前面 4 種 broker ,因?yàn)殚_啟這個參數(shù),消息首先會存儲在堆外內(nèi)存中,并且 RocketMQ 提供了內(nèi)存鎖定的功能,其追加性能能得到一定的保障,這樣可以做到在內(nèi)存使用層面的讀寫分離,即寫消息是直接寫入堆外內(nèi)存,消費(fèi)消息直接從 pagecache中讀,然后定時將堆外內(nèi)存的消息寫入 pagecache。但這種方案隨之帶來的就是可能存在消息丟失,如果對消息非常嚴(yán)謹(jǐn)?shù)脑?,建議擴(kuò)容集群,或遷移topic到新的集群。  

同時在做 Broker 服務(wù)器巡檢的時候,可以通過去通過如下命令去查看 broker 一次消息追加是否會超過 500 ms。

RocketMQ broker busy的示例分析  

在這個圖中我們看到在設(shè)置了 transientStorePoolEnable 為 true 的情況下,雖然一天只有一條超過500ms的消息,但也值得警惕了,由于對系統(tǒng)內(nèi)核參數(shù)掌握程度不夠,這種情況,估計只能走集群擴(kuò)容的路子了。但如果一天消息量巨大而且出現(xiàn)頻率不高的情況,由于有重試機(jī)制,倒不會帶來太大的問題。如果出現(xiàn)太多的錯誤,  建議集群擴(kuò)容。

本文接下來想重點(diǎn)探討一下 [TIMEOUT_CLEAN_QUEUE]broker busy 這種情況。

BrokerFastFailure#cleanExpiredRequest

while (true) {
    try {
        if (!this.brokerController.getSendThreadPoolQueue().isEmpty()) {
            final Runnable runnable = this.brokerController.getSendThreadPoolQueue().peek();
            if (null == runnable) {
                break;
            }
            final RequestTask rt = castRunnable(runnable);
            if (rt == null || rt.isStopRun()) {
                break;
            }

            final long behind = System.currentTimeMillis() - rt.getCreateTimestamp();
            if (behind >= this.brokerController.getBrokerConfig().getWaitTimeMillsInSendQueue()) {
                if (this.brokerController.getSendThreadPoolQueue().remove(runnable)) {
                    rt.setStopRun(true);
                    rt.returnResponse(RemotingSysResponseCode.SYSTEM_BUSY, String.format("[TIMEOUT_CLEAN_QUEUE]broker busy, start flow control for a while, period in queue: %sms, size of queue: %d", behind, this.brokerController.getSendThreadPoolQueue().size()));
                }
            } else {
                break;
            }
        } else {
            break;
        }
    } catch (Throwable ignored) {
    }
}
 

可以看出來,拋出這種錯誤,在 broker 還沒有發(fā)送“嚴(yán)重”的 pagecache 繁忙,即消息追加到內(nèi)存中的最大時延沒有超過 1s,通常追加是很快的,絕大部分都會低于1ms,但可能會由于出現(xiàn)一個超過200ms的追加時間,導(dǎo)致排隊中的任務(wù)等待時間超過了200ms,則此時會觸發(fā)broker 端的快速失敗,讓請求快速失敗,便于客戶端快速重試。但是這種請求并不是實(shí)時的,而是每隔10s 檢查一遍。

值得注意的是,一旦出現(xiàn) TIMEOUT_CLEAN_QUEUE,可能在一個點(diǎn)會有多個這樣的錯誤信息,具體多少與當(dāng)前積壓在待發(fā)送隊列中的個數(shù)有關(guān)。

以上是“RocketMQ broker busy的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI