1. 程式人生 > >當說起message queue的時候,都在說什麼?

當說起message queue的時候,都在說什麼?

接觸了一些message system的系統(大部分是kafka),對message queue的作用和關鍵點有了一些瞭解。這些就談談我的認識,和使用注意事項。

message queue的作用

查閱了材料發現總結下來,列舉的理由有十幾條之多,但是直接貌似沒有任何聯絡和組織方式。很是不好理解。我在這裡使用模型的變化來闡述我自己的理解:
這裡寫圖片描述
從上面的演化圖來看,有了訊息佇列後的一個本質變化就是把收訊息和接訊息的任務都扔給了第三方,其實這就是軟體行業中最一般的做法如果要獲得軟體的靈活性和擴充套件性,那麼就開始加中間層。計算機網路是這麼做的,同樣作業系統也是這麼做的。
而考慮具體的好處這個問題和系統會出現什麼問題是手心手背的關係。我們就來一塊一塊的說。
我們假設我們要做一個買票系統。資料庫使用mysql,前面只有一個售票程式來操作資料。這時候的模型就是第一個模組的樣子。初期的時候一切都很完美,這個網站只擁有1萬用戶,每天只賣500張票。
後來發現有些背後的mysql總是宕機,導致使用者訂票總是不成功,所以就想著怎麼把使用者的訂單資訊先存下來,然後等mysql恢復後馬上繼續處理。這時候你就開始想著建立一個訊息快取佇列,然後程式自然形成了一個生產者消費者模型。同時你還會發現這個不僅僅有訊息快取的好處,還有發現訊息現在是可以被儲存了(或者說很便捷和自然的儲存了)。以前那些因為程式bug處理失敗的訊息可以被重複處理了。還有就是哪天突然要在mysql之上加上一層redis,那其實也不必修改上游程式。總結下來:
1. 緩衝 – 訊息的快取,當下遊處於宕機狀態,訊息可以被快取等待重啟後繼續處理。
2. 解耦 – 專案之間解耦,形成各種微服務
3. 冗餘
4. 送達保證
5. 順序保證能實現了

再後來你的系統的使用者增加到了100萬,而且因為是買的火車票,所以一到過節訂單就出現高峰,這時候辛虧你有了訊息佇列可以幫你快取。
6. 消除峰值 – 即訊息均衡,當訊息的生產速度差距很大的時候,訊息可以被快取,然後轉發其他空閒的服務上或者等待等後續措施。

後來再發現一個訊息佇列因為不夠儲存高峰期間儲蓄的資料了,這時候再增加下游的消費者處理能力很浪費,因為平時你用不著。這時候發現增加一個訊息佇列服務的成本去很低,那麼開始擴充套件這裡。
7. 擴充套件性

其他feature:
1. 非同步通訊
這個是好是壞,全看實際的引用場景。對於實時要求性很高,但是不要求訊息全部保證被處理就是無所謂的特性。

  1. 附贈的feature(只是更方便吧)
    因為訊息快取的獨立,可以對其處理速度監控,從而得知系統的負載能力。

如果學習一個message queue?

訊息可達性保證機制

這個機制或者約定更確切些,就是描述系統到底怎麼client進行互動,確保資訊是正確的到達了目的地。一般的訊息保證機制有:
1.至多一次,保證絕對不重複發,但是有丟資料情況。這種情況server處理是最簡單的,發完了就不管了,不需要和client互動。

at-most-once delivery means that for each message handed to the mechanism, that message is delivered zero or one times; in more casual terms it means that messages may be lost.

2.至少一次,保證一定client接收到了資訊,如果不能確定client接收到了資訊會重複發。做到這點server只要一直髮知道接收到了client的ack。

at-least-once delivery means that for each message handed to the mechanism potentially multiple attempts are made at delivering it, such that at least one succeeds; again, in more casual terms this means that messages may be duplicated but not lost.

3.精確的一次,保證不重複發但也不丟資料。exactly-once是最難保證的,因為這涉及到通訊中的很多情況。

exactly-once delivery means that for each message handed to the mechanism exactly one delivery is made to the recipient; the message can neither be lost nor duplicated.

The first one is the cheapest—highest performance, least implementation overhead—because it can be done in a fire-and-forget fashion without keeping state at the sending end or in the transport mechanism. The second one requires retries to counter transport losses, which means keeping state at the sending end and having an acknowledgement mechanism at the receiving end. The third is most expensive—and has consequently worst performance—because in addition to the second it requires state to be kept at the receiving end in order to filter out duplicate deliveries.

為什麼保證不了訊息傳送?

  1. The message is sent out on the network?
  2. The message is received by the other host?
  3. The message is put into the target actor’s mailbox?
  4. The message is starting to be processed by the target actor?
  5. The message is processed successfully by the target actor?

其實就從訊息傳遞從出發到結果的整個過程,狀體包括出發、路上、進門、喝茶、出門和回家通報。
其中在路上需要花多少時間誰都不知道,還有沒有萬一進門後被真“喝茶”後,不返回通報的你讓傳送者的家人怎麼辦?

訊息順序保證機制

  1. 保證訊息一定是順序到達的,這個地方需要考慮如果是一個kafka的系統,同一個group下的不同consumer之間的順序怎麼保證?
  2. 不保證訊息一定順序到達

reference