分析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更優秀(其他的訊息佇列大家也都可以瞭解瞭解)
動手玩玩去!~
根據下面的文章有感而發:(裡面這貨是大牛)