爲什麼需要消息隊列?使用消息隊列有什麼好處?

一、消息隊列的特性

業務無關,一個具有普適性質的消息隊列組件不需要考慮上層的業務模型,只做好消息的分發就可以了,上層業務的不同模塊反而需要依賴消息隊列所定義的規範進行通信。

FIFO,先投遞先到達的保證是一個消息隊列和一個buffer的本質區別。

容災,對於普適的消息隊列組件來說,節點的動態增刪和消息的持久化,都是支持其容災能力的重要基本特性。當然,這個特性對於遊戲服務器中大部分應用中的消息隊列來說不是必須的,這個也是跟應用情景有關的,很多時候沒有這種持久化的需求。

性能,這個不必多說了,消息隊列的吞吐量上去了,整個系統的內部通信效率也會有提高。

二、爲什麼需要消息隊列?

當系統中出現“生產“和“消費“的速度或穩定性等因素不一致的時候,就需要消息隊列,作爲抽象層,彌合雙方的差異。“ 消息 ”是在兩臺計算機間傳送的數據單位。消息可以非常簡單,例如只包含文本字符串;也可以更復雜,可能包含嵌入對象。消息被髮送到隊列中,“ 消息隊列 ”是在消息的傳輸過程中保存消息的容器 。

舉幾個例子

  • 1)業務系統觸發短信發送申請,但短信發送模塊速度跟不上,需要將來不及處理的消息暫存一下,緩衝壓力。就可以把短信發送申請丟到消息隊列,直接返回用戶成功,短信發送模塊再可以慢慢去消息隊列中取消息進行處理。

  • 2)調遠程系統下訂單成本較高,且因爲網絡等因素,不穩定,攢一批一起發送。

  • 3)任務處理類的系統,先把用戶發起的任務請求接收過來存到消息隊列中,然後後端開啓多個應用程序從隊列中取任務進行處理。

三、使用消息隊列有什麼好處?

3.1、提高系統響應速度

使用了消息隊列,生產者一方,把消息往隊列裏一扔,就可以立馬返回,響應用戶了。無需等待處理結果。

處理結果可以讓用戶稍後自己來取,如醫院取化驗單。也可以讓生產者訂閱(如:留下手機號碼或讓生產者實現listener接口、加入監聽隊列),有結果了通知。獲得約定將結果放在某處,無需通知。

3.2、提高系統穩定性

考慮電商系統下訂單,發送數據給生產系統的情況。電商系統和生產系統之間的網絡有可能掉線,生產系統可能會因維護等原因暫停服務。如果不使用消息隊列,電商系統數據發佈出去,顧客無法下單,影響業務開展。兩個系統間不應該如此緊密耦合。應該通過消息隊列解耦。同時讓系統更健壯、穩定。

異步化、解耦、消除峯值
以上三點其實可以用一個例子來解釋——設想有一款MMO遊戲,沒有人肉寫的緩存層或者ORM,所有邏輯節點都直連MySQL,邏輯節點內除了要關注場景、戰鬥、交互等複雜邏輯以外,還要有個拼SQL語句的模塊,想想簡直是蛋疼。先考慮一下這樣設計的弊端所在:

  • 邏輯節點與Db的交互會有大量IO,即使把與Db交互的模塊耦合在邏輯節點內,其實現對你來說是黑盒,如果內部是同步實現的,那就直接卡你遊戲主邏輯,就因爲一次存盤操作,玩家們都掉線了,服務器也可以關掉了。

  • 那麼我們改進一下,針對1的情況,可以把這個模塊做到一個線程裏掛在邏輯節點上。這樣其實邏輯節點跟這個Db前端模塊的交互就會基於一個比較原始的消息隊列。但是這樣還有一個壞處,那就是這兩種任務一種是計算密集的(玩家的邏輯處理)、一種是IO密集的(只負責寫入讀取MySQL),搞到一個節點中,擴展起來會非常麻煩,而且耦合度太高。比如說現在發現場景放單節點上有瓶頸,要按場景分節點,那麼這種掛在上面的數據模塊怎麼跟其他場景的交互呢?

  • 峯值的問題。在分佈式系統中,一次分佈式事務關聯的是多個節點,其中每一個節點出現問題都會成爲整個事務處理流程中的瓶頸。如果邏輯節點與數據庫之間沒有一個起到緩衝作用的節點,那就是每次操作都要訪問數據庫,對於MMO來說,一個玩家上線load幾百K數據,一個服10萬個玩家上線已經足夠搞垮一個mysql節點了。如果直接搞垮還是比較好的結果,至少是前面的玩家確實登錄上去了並且可以正常遊戲,後面的玩家登錄不上。但是很可惜,十年前開始流行的C10K說法就是在講:併發量上來之後,會造成chain reaction,大量的併發不會直接掛掉你的mysql節點,但是會拖慢速度,降低吞吐量,一個玩家的請求由於處理時間太長,導致玩家放棄重試,但是對於後端來說,對該玩家之前的處理過程消耗的資源就全部浪費了,陷入惡性循環。

所以,這種情景下,一個介於邏輯節點和db節點之間的緩存節點就是理所當然的事情了。這個緩存節點其實很多時候也可以看作是一個更復雜的消息隊列節點。

四、爲什麼需要分佈式?

4.1、多系統協作需要分佈式

消息隊列中的數據需要在多個系統間共享數據才能發揮價值。所以必須提供分佈式通信機制、協同機制。

4.2、單系統內部署環境需要分佈式

單系統內部,爲了更好的性能、爲了避免單點故障,多爲集羣環境。集羣環境中,應用運行在多臺服務器的多個JVM中;數據也保存在各種類型的數據庫或非數據庫的多個節點上。爲了滿足多節點協作需要,需要提供分佈式的解決方案。

五、分佈式環境下需要解決哪些問題?

5.1、併發問題

需進行良好的併發控制。確保“線程安全“。不要出現一個訂單被出貨兩次。不要出現顧客A下的單,發貨發給了顧客B等情況。

5.2、簡單的、統一的操作機制

需定義簡單的,語義明確的,業務無關的,恰當穩妥的統一的訪問方式。

5.3、容錯

控制好單點故障,確保數據安全。

5.4、可橫向擴展

可便捷擴容。

六、如何實現?

成熟的消息隊列中間件產品太多了,族繁不及備載。成熟產品經過驗證,接口規範,可擴展性強。

結合事業環境因素、組織過程遺產、實施運維考慮、技術路線考慮、開發人員情況等原因綜合考慮。

七、常見消息隊列對比和選型

在這裏插入圖片描述

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