高併發系統設計十七-消息隊列,如何降低消息隊列系統中消息的延遲

消息隊列,如何降低消息隊列系統中消息的延遲

當項目中引入了消息隊列時,增加了系統的複雜度。需要考慮如何保證消息不會丟失、如何避免消息重複帶來的影響、還需要考慮消息延遲情況,即消費性能的問題。

場景:上游服務器產生訂單數據,並將數據放入消息隊列服務中,但是下游系統消費較慢,造成消息隊列出現大量堆積。下游系統處理消息出現了延遲。

如何來解決這個問題呢?

  • 監控消息的延遲
  • 減少消息延遲的正確做法

1 如何監控消息延遲

監控消息的延遲有兩種方式:

  • 使用消息隊列提供的工具,通過監控消息的堆積來完成監控
  • 通過生成監控消息的方式來監控消息的延遲情況

1.1 使用消息隊列提供的工具

1、在 Kafka 中,提供了 ”kafka-consoumer-groups.sh“ 在 bin 目錄下。

通過命令查看消息積累情況

./bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group test-consumer-group

2、使用工具 JMX
Kafka 通過 JMX 暴露了消息堆積的數據,我在本地啓動了一個 console consumer,然後使用 jconsole 連接 consumer 就可以看到 consumer 的堆積數據了

1.2 通過生成監控消息的方式監控消息的延遲

1、定義一個特殊的信息,
2、啓動一個監控程序將這個消息定時地循環寫入到消息隊列中
3、消息的內容可以是生成消息的時間戳並作爲隊列的消費這消費數據
4、業務處理程序消費到這個數據時可以直接丟棄掉
5、監控程序在消費到這個消息就可以和消息的生成時間做比較
6、如果時間差達到某一個閥值就報警

2 減少消息延遲的正確做法

減少消息的處理演示,可以在消費端和消息隊列自身兩個地方進行優化。

2.1 在消費端提升

  • 優化消費代碼提升消費性能
  • 增加消費者數量(Kafka不支持)

如果不能添加 consumer ,可以在一個 consumer 中提升消息的並行度,採用多線程來進行處理,以便提高消息消費的吞吐量。

2.2 消息隊列

消息隊列本身在讀取性能優化方面可以考慮

  • 消息的存儲
  • 零拷貝技術

消息存儲,普通的數據庫來存儲消息,但是受限於數據庫的性能瓶頸,如果使用本地磁盤作爲存儲介質。Page Cache 的存儲就可以提升消息的讀取速度。

零拷貝技術,儘量較少拷貝的次數。
在讀取消息隊列的數據時,其實就是把磁盤中的數據通過網絡發送給消費客戶端,涉及了4次數據拷貝步驟:

  • 數據從磁盤拷貝到內核緩衝區;
  • 系統調用將內核緩存區的數據拷貝到用戶緩衝區;
  • 用戶緩衝區的數據被寫入到 Socket 緩衝區中;
  • 操作系統再將 Socket 緩衝區的數據拷貝到網卡的緩衝區中。

操作系統提供了 Sendfile 函數可以減少數據被拷貝的次數。使用了 Sendfile 之後,在內核緩衝區的數據不會被拷貝到用戶緩衝區而是直接被拷貝到 Socket 緩衝區,節省了一次拷貝的過程提升了消息發送的性能。高級語言中對於 Sendfile 函數有封裝,比如說在 Java 裏面的 java.nio.channels.FileChannel 類就提供了 transferTo 方法提供了 Sendfile 的功能。

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