iT邦幫忙

1

聊天軟體實作(4): 把服務解耦的MQ

  • 分享至 

  • xImage
  •  

一個完整的聊天軟體,會至少包含四個部分。為了避免單點故障這種重大意外,會交由不同伺服器或容器(Pod)處理,後續舉例會提到:

(1) 使用者相關服務
登入、個人資訊、好友資訊、群聊資訊、在聊天室的發言權限....等。

(2) 在線狀態服務
這邊有兩件小任務:判定使用者上線,以及相關好友上線推播。跟扇出(Fanout)設計有關。

(3) 訊息處理服務
Websocket 解決了通訊即時性的問題,提供使用者間訊息傳送媒介。

(4) 推播服務
有人發送訊息後,跳出訊息通知、被標註提及、未讀訊息數等,都需要另外處理。

把服務(Servive)拆分,讓不同部分的 Code 負責不同的工作,提高了後續變動的彈性和維護性。當 A 服務做的事情不因為 B 服務影響,業務邏輯互相獨立,擴充性大大提高。

也就是所謂的解耦(Decoupling)。

當服務之間像流水線分工後,這時還需要溝通,比如 A 服務做完兩件半成品,需要告訴 B 服務有新的物件要幫忙處理。

直觀上有兩種方式:

一個是讓 A 服務直接去告知 B 服務,這時他必須親自確認 B 服務收到訊息,比如透過 TCP/IP,傳送定義好的檔案或格式,如:純文字、XML 或 JSON。

https://ithelp.ithome.com.tw/upload/images/20220810/20139626qh6tV66X5q.png

另一種是,透過郵局或物流中心,先轉發至可配送訊息的中介,後續的通知和處理就靠物流中心處理。使用訊息柱列(Message Queue, MQ),就是這一種異步溝通的方式。

https://ithelp.ithome.com.tw/upload/images/20220810/20139626bELqDhB5JM.png

MQ是個柱列(Queue),FIFO,如同郵局整理信件,先寄的信優先送出。這時候可以達到排隊的效果。此時的 A服務便是生產者(Producer), B服務便是消費者(Consumer),傳送的message跟寫信一樣,必須定義收件地址和內容。

對於聊天訊息軟體而言,假設今天有使用者要發送訊息,(1) 使用者相關服務伺服器/ Pod ,可能需要先判斷使用者有沒有被黑名單,或是在群聊中有沒有發言權限,完成之後再交由 (3) 訊息處理服務的 Websocket 伺服器/ Pod 處理。

設想一個情況,同時有多台(1) 使用者相關服務送出發訊息的 request ,如何確保訊息的順序? 這時候MQ可以讓大家乖乖排隊。

另外有幾個好處:
(1) 消費者 Consumer 有空時才會處理 message。除了解耦的乾淨俐落外,還提高處理效能。
(2) 生產者 Publisher 不需知道消費者 Consumer 實際位置(IP)。
(3) 生產者 Publisher、柱列Queue、消費者 Consumer 數量可隨需求增減。系統擴張性好。

當然MQ不是萬能,還必須考慮 message 丟失,問題是丟失後怎麼重試。如果重試之後,怎麼辨識有沒有處理過這 message。

總結: 在幾種場景我們可以考慮訊息柱列(Message Queue, MQ)
(1) 排隊,例如: 千人搶票、股票掛單交易
(2) 異步解耦,例如: 可接受些微延遲的寄mail、消耗CPU的事情

上一篇: 聊天軟體實作(3): 訊息怎麼推送-心跳包


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言