訊息佇列系列一:訊息佇列應用

笨小孩發表於2021-05-24
[TOC]

以下內容為非同步佇列介紹

  • 訊息是兩個服務之間溝通的媒介
  • 訊息可以有很多種,簡單到字串(如簡訊資訊),也可以是物件
  • 佇列就是兩個服務之間進行溝通的訊息的容器或者載體
  • 佇列就是排隊中的一組訊息資料
  • 佇列就是一組有序的訊息資料
  • 佇列可以是陣列array,也可以是連結串列list,也可以是有序集合,只要該資料能承載訊息並且有順序
  • 常見的佇列大部分是基於連結串列的list
  • 常用於解決併發系統中的資源一致性問題(如超賣)
  • 提升峰值的處理能力,同時保證訊息的順序性、可恢復性、必送達性
  • mysql
  • redis
    • 基於list的lpush+rpop實現的生產/消費模式
    • 基於pub/sub的釋出/訂閱模式
    • 基於SortedSet有序集合的實現
    • 基於 Stream 型別的實現
  • 專業訊息中介軟體
    • RabbitMQ
    • Kafka
  • 高併發,大流量
  • 耗時特別長同時還不需要立即返回處理結果(非同步處理)
  • 流量削峰(如秒殺)
  • 應用解耦(如訂單系統和庫存系統)
  • 非同步通訊(傳送簡訊、郵件)
  • 順序性(熱點資料排序)
指標 比較
可靠性 rabbitMq > mysql > redis
效能 redis> rabbitMq > mysql
複雜度 rabbitMq > mysql > redis

因此,我們常用選型如下

  • 如果對效能要求較高或者對安全可靠性要求不高的情形下,優先考慮基於redis實現佇列
  • 如果對訊息的可靠性要求較高並且對效能兼顧的情況下,優先考慮專業訊息中介軟體
  • mysql訊息中介軟體很少用到

redis實現非同步訊息分析

基於list的lpush+rpop實現的生產/消費模式

優點:

  • 低延遲(訊息幾乎無延遲)

缺點:

  • 做消費者確認ACK麻煩,不能保證消費者消費訊息後是否成功處理的問題(當機或處理異常等),通常需要維護一個Pending列表,保證訊息處理確認。
  • 不能做廣播模式,如pub/sub,訊息釋出/訂閱模型
  • 不能重複消費,一旦消費就會被刪除
  • 不支援分組消費

基於pub/sub的釋出/訂閱模式

此模式允許生產者只生產一次訊息,由中介軟體負責將訊息複製到多個訊息佇列,每個訊息佇列由對應的消費組消費。
優點

  • 典型的廣播模式,一個訊息可以釋出到多個消費者
  • 多通道訂閱,消費者可以同時訂閱多個通道,從而接收多類訊息
  • 訊息即時傳送,訊息不用等待消費者讀取,消費者會自動接收到通道釋出的訊息

缺點

  • 訊息一旦釋出,不能接收。換句話就是釋出時若客戶端不線上,則訊息丟失,不能尋回
  • 不能保證每個消費者接收的時間是一致的
  • 若消費者客戶端出現訊息積壓,到一定程度,會被強制斷開,導致訊息意外丟失。通常發生在訊息的生產遠大於消費速度時

可見,Pub/Sub 模式不適合做訊息儲存,訊息積壓類的業務,而是擅長處理廣播,即時通訊,即時反饋的業務。

基於SortedSet有序集合的實現

優點

  • 可以自定義訊息ID,在訊息ID有意義時,比較重要。

缺點

  • 不允許重複訊息(因為是集合),同時訊息ID確定有錯誤會導致訊息的順序出錯。

基於 Stream 型別的實現

TODO

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章