1. 程式人生 > >分析redis訊息佇列和kafka來解決分散式事務場景

分析redis訊息佇列和kafka來解決分散式事務場景

1、系統A(扣減托盤)【訊息生產者】

2、系統B(扣減押金)【訊息消費者】

業務描述:

兩套系統,A中扣減托盤,B中對應的要扣減押金;A中托盤歸還,B中押金返還

利用訊息佇列來解決分散式事務過程:

傳送方【生產者】:(不關心接收方狀態,只需要確定本地OK,訊息推送即可)

1、傳送的訊息首先需要入庫(1⃣表結構:【訊息ID,內容,相關事務的ID】)

2、執行本地邏輯操作並commit,傳送訊息(增加延遲處理,超時未傳送成功的—>入庫(新的異常訊息表),開啟新執行緒繼續傳送,成功則刪除異常訊息表資訊)

到此為止傳送成功

接收方【消費者】:(也不關心傳送方狀態,只需要接收訊息,執行本地操作即可)

1、接收的訊息也先入庫(1⃣表結構同上)

2、開啟新執行緒處理訊息,確保訊息一定能執行成功

執行緒均使用ThreadPoolExecutor執行緒池

1⃣處的好處:

1、訊息內容本地持久化,如果真的出現什麼問題,便於雙方排查問題

2、針對接收方來說,可防止訊息的重複傳送情況

當然這個過程需要確保訊息中介軟體功能完全正常,就算宕機也沒有任何影響

本地的邏輯操作和傳送訊息都可以有超時的判定,但是訊息的出佇列呢?

下面說下redis訊息佇列弊端:

訊息從queue裡面出來,還未到達消費者前網路中斷或者各種原因導致訊息丟失,而接受者並不知道有此訊息最終導致分散式事務不一致的情況,並且該情況的反應時間有可能是幾個月後或者更長時間,排查問題也很麻煩

引入訊息佇列kafka的優勢:

kafka本身的訊息支援持久化,訊息本身以快照的形式儲存在磁碟中(並非redis是在記憶體中),再加上kafka訊息佇列的特性—>(並非真正意義上的出佇列,而是有類似指標只是指向訊息的消費情況,即永遠指向下一個待消費資訊,訊息還是在佇列中存在,而客戶端可以手動控制訊息是否被成功消費),這點已經足以可以用kafka來取代原生的redis訊息佇列,在加上kafka與zookeeper無縫整合,可以在zookeeper中可以很好的監控kafka的brokers(存放訊息的倉庫)、topics(訊息的主題)、partitions(倉庫裡面的分割槽)以及指標的offset(偏移量,即訊息的消費情況)

最後kafka的吞吐量和叢集方式都比redis更優秀(其他的訊息佇列大家也都可以瞭解瞭解)

動手玩玩去!~

根據下面的文章有感而發:(裡面這貨是大牛)