人生是一連串的難題,解決人生問題的首要方案,乃是自律。前端
1、消息隊列的特性
2、爲何須要消息隊列?
3、使用消息隊列有什麼好處?
4、爲何須要分佈式?
5、分佈式環境下須要解決哪些問題?
6、如何實現?
7、常見消息隊列對比和選型
業務無關,一個具備普適性質的消息隊列組件不須要考慮上層的業務模型,只作好消息的分發就能夠了,上層業務的不一樣模塊反而須要依賴消息隊列所定義的規範進行通訊。mysql
FIFO,先投遞先到達的保證是一個消息隊列和一個buffer的本質區別。react
容災,對於普適的消息隊列組件來講,節點的動態增刪和消息的持久化,都是支持其容災能力的重要基本特性。固然,這個特性對於遊戲服務器中大部分應用中的消息隊列來講不是必須的,這個也是跟應用情景有關的,不少時候沒有這種持久化的需求。sql
性能,這個沒必要多說了,消息隊列的吞吐量上去了,整個系統的內部通訊效率也會有提升。數據庫
當系統中出現「生產「和「消費「的速度或穩定性等因素不一致的時候,就須要消息隊列,做爲抽象層,彌合雙方的差別。「 消息 」是在兩臺計算機間傳送的數據單位。消息能夠很是簡單,例如只包含文本字符串;也能夠更復雜,可能包含嵌入對象。消息被髮送到隊列中,「 消息隊列 」是在消息的傳輸過程當中保存消息的容器 。後端
舉幾個例子緩存
1)業務系統觸發短信發送申請,但短信發送模塊速度跟不上,須要未來不及處理的消息暫存一下,緩衝壓力。就能夠把短信發送申請丟到消息隊列,直接返回用戶成功,短信發送模塊再能夠慢慢去消息隊列中取消息進行處理。安全
2)調遠程系統下訂單成本較高,且由於網絡等因素,不穩定,攢一批一塊兒發送。服務器
3)任務處理類的系統,先把用戶發起的任務請求接收過來存到消息隊列中,而後後端開啓多個應用程序從隊列中取任務進行處理。網絡
使用了消息隊列,生產者一方,把消息往隊列裏一扔,就能夠立馬返回,響應用戶了。無需等待處理結果。
處理結果可讓用戶稍後本身來取,如醫院取化驗單。也可讓生產者訂閱(如:留下手機號碼或讓生產者實現listener接口、加入監聽隊列),有結果了通知。得到約定將結果放在某處,無需通知。
考慮電商系統下訂單,發送數據給生產系統的狀況。電商系統和生產系統之間的網絡有可能掉線,生產系統可能會因維護等緣由暫停服務。若是不使用消息隊列,電商系統數據發佈出去,顧客沒法下單,影響業務開展。兩個系統間不該該如此緊密耦合。應該經過消息隊列解耦。同時讓系統更健壯、穩定。
以上三點其實能夠用一個例子來解釋——設想有一款MMO遊戲,沒有人肉寫的緩存層或者ORM,全部邏輯節點都直連MySQL,邏輯節點內除了要關注場景、戰鬥、交互等複雜邏輯之外,還要有個拼SQL語句的模塊,想一想簡直是蛋疼。先考慮一下這樣設計的弊端所在:
- 邏輯節點與Db的交互會有大量IO,即便把與Db交互的模塊耦合在邏輯節點內,其實現對你來講是黑盒,若是內部是同步實現的,那就直接卡你遊戲主邏輯,就由於一次存盤操做,玩家們都掉線了,服務器也能夠關掉了。
- 那麼咱們改進一下,針對1的狀況,能夠把這個模塊作到一個線程裏掛在邏輯節點上。這樣其實邏輯節點跟這個Db前端模塊的交互就會基於一個比較原始的消息隊列。可是這樣還有一個壞處,那就是這兩種任務一種是計算密集的(玩家的邏輯處理)、一種是IO密集的(只負責寫入讀取MySQL),搞到一個節點中,擴展起來會很是麻煩,並且耦合度過高。好比說如今發現場景放單節點上有瓶頸,要按場景分節點,那麼這種掛在上面的數據模塊怎麼跟其餘場景的交互呢?
- 峯值的問題。在分佈式系統中,一次分佈式事務關聯的是多個節點,其中每個節點出現問題都會成爲整個事務處理流程中的瓶頸。若是邏輯節點與數據庫之間沒有一個起到緩衝做用的節點,那就是每次操做都要訪問數據庫,對於MMO來講,一個玩家上線load幾百K數據,一個服10萬個玩家上線已經足夠搞垮一個mysql節點了。若是直接搞垮仍是比較好的結果,至少是前面的玩家確實登陸上去了而且能夠正常遊戲,後面的玩家登陸不上。可是很惋惜,十年前開始流行的C10K說法就是在講:併發量上來以後,會形成chain reaction,大量的併發不會直接掛掉你的mysql節點,可是會拖慢速度,下降吞吐量,一個玩家的請求因爲處理時間太長,致使玩家放棄重試,可是對於後端來講,對該玩家以前的處理過程消耗的資源就所有浪費了,陷入惡性循環。
因此,這種情景下,一個介於邏輯節點和db節點之間的緩存節點就是理所固然的事情了。這個緩存節點其實不少時候也能夠看做是一個更復雜的消息隊列節點。
消息隊列中的數據須要在多個系統間共享數據才能發揮價值。因此必須提供分佈式通訊機制、協同機制。
單系統內部,爲了更好的性能、爲了不單點故障,多爲集羣環境。集羣環境中,應用運行在多臺服務器的多個JVM中;數據也保存在各類類型的數據庫或非數據庫的多個節點上。爲了知足多節點協做須要,須要提供分佈式的解決方案。
需進行良好的併發控制。確保「線程安全「。不要出現一個訂單被出貨兩次。不要出現顧客A下的單,發貨發給了顧客B等狀況。
需定義簡單的,語義明確的,業務無關的,恰當穩妥的統一的訪問方式。
控制好單點故障,確保數據安全。
可便捷擴容。
成熟的消息隊列中間件產品太多了,族繁不及備載。成熟產品通過驗證,接口規範,可擴展性強。
結合事業環境因素、組織過程遺產、實施運維考慮、技術路線考慮、開發人員狀況等緣由綜合考慮。