分佈式事物2 基於rocketmq

分佈式事物2 基於rocketmq 

從rocketmq的官網可以看到,它又以下幾種消息類型:

1)發送同步消息

這種可靠性同步地發送方式使用的比較廣泛,比如:重要的消息通知,短信通知

2)發送異步消息

異步消息通常用在對響應時間敏感的業務場景,即發送端不能容忍長時間地等待Broker的響應。

3)單向發送消息

這種方式主要用在不特別關心發送結果的場景,例如日誌發送。

 消息消費:

    1)負載均衡模式

      消費者採用負載均衡方式消費消息,多個消費者共同消費隊列消息,每個消費者處理的消息不同

    2)廣播模式

      消費者採用廣播的方式消費消息,每個消費者消費的消息都是相同的

4)順序消息

消息有序指的是可以按照消息的發送順序來消費(FIFO)。RocketMQ可以嚴格的保證消息有序,可以分爲分區有序或者全局有序。

順序消費的原理解析,在默認的情況下消息發送會採取Round Robin輪詢方式把消息發送到不同的queue(分區隊列);而消費消息的時候從多個queue上拉取消息,這種情況發送和消費是不能保證順序。但是如果控制發送的順序消息只依次發送到同一個queue中,消費的時候只從這個queue上依次拉取,則就保證了順序。當發送和消費參與的queue只有一個,則是全局有序;如果多個queue參與,則爲分區有序,即相對每個queue,消息都是有序的。

5)延時

比如電商裏,提交了一個訂單就可以發送一個延時消息,1h後去檢查這個訂單的狀態,如果還是未付款就取消訂單釋放庫存。

// org/apache/rocketmq/store/config/MessageStoreConfig.java
private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";

現在RocketMq並不支持任意時間的延時,需要設置幾個固定的延時等級,從1s到2h分別對應着等級1到18

6)批量消息

批量發送消息能顯著提高傳遞小消息的性能。限制是這些批量消息應該有相同的topic,相同的waitStoreMsgOK,而且不能是延時消息。此外,這一批消息的總大小不應超過4MB。如果消息的總長度可能大於4MB時,這時候最好把消息進行分割

7)過濾消息

RocketMq可以基於tag對消息進行過濾,可以使用SQL表達式篩選消息

8)事物消息

上圖說明了事務消息的大致方案,其中分爲兩個流程:正常事務消息的發送及提交、事務消息的補償流程。

1)事務消息發送及提交

(1) 發送消息(half消息)。

(2) 服務端響應消息寫入結果。

(3) 根據發送結果執行本地事務(如果寫入失敗,此時half消息對業務不可見,本地邏輯不執行)。

(4) 根據本地事務狀態執行Commit或者Rollback(Commit操作生成消息索引,消息對消費者可見)

2)事務補償

(1) 對沒有Commit/Rollback的事務消息(pending狀態的消息),從服務端發起一次“回查”

(2) Producer收到回查消息,檢查回查消息對應的本地事務的狀態

(3) 根據本地事務狀態,重新Commit或者Rollback

其中,補償階段用於解決消息Commit或者Rollback發生超時或者失敗的情況。

3)事務消息狀態

事務消息共有三種狀態,提交狀態、回滾狀態、中間狀態:

  • TransactionStatus.CommitTransaction: 提交事務,它允許消費者消費此消息。
  • TransactionStatus.RollbackTransaction: 回滾事務,它代表該消息將被刪除,不允許被消費。
  • TransactionStatus.Unknown: 中間狀態,它代表需要檢查消息隊列來確定狀態。

事物消息使用限制:

  1. 事務消息不支持延時消息和批量消息。
  2. 爲了避免單個消息被檢查太多次而導致半隊列消息累積,我們默認將單個消息的檢查次數限制爲 15 次,但是用戶可以通過 Broker 配置文件的 transactionCheckMax參數來修改此限制。如果已經檢查某條消息超過 N 次的話( N = transactionCheckMax ) 則 Broker 將丟棄此消息,並在默認情況下同時打印錯誤日誌。用戶可以通過重寫 AbstractTransactionCheckListener 類來修改這個行爲。
  3. 事務消息將在 Broker 配置文件中的參數 transactionMsgTimeout 這樣的特定時間長度之後被檢查。當發送事務消息時,用戶還可以通過設置用戶屬性 CHECK_IMMUNITY_TIME_IN_SECONDS 來改變這個限制,該參數優先於 transactionMsgTimeout 參數。
  4. 事務性消息可能不止一次被檢查或消費,消費端要冪等處理
  5. 提交給用戶的目標主題消息可能會失敗,目前這依日誌的記錄而定。它的高可用性通過 RocketMQ 本身的高可用性機制來保證,如果希望確保事務消息不丟失、並且事務完整性得到保證,建議使用同步的雙重寫入機制。
  6. 事務消息的生產者 ID 不能與其他類型消息的生產者 ID 共享。與其他類型的消息不同,事務消息允許反向查詢、MQ服務器能通過它們的生產者 ID 查詢到消費者。

參考:https://www.bilibili.com/video/av71654125?p=33

擴展:

1)windows下用命令行操作環境變量

切換到超級管理員命令行窗口

使用cmd命令添加path環境變量 當前窗口有效              
在cmd下輸入: path=%path%;D:/Anaconda  接着按"Enter"回車鍵,其中: D:/Anaconda 是Python的安裝目錄。

Windows10命令行設置環境變量

set  可以設置臨時環境變量,只有在當前窗口下有效

語法:set name=value

set name 可以查看環境變量

setx 可以永久設置環境變量

setx /m 永久設置環境變量

setx /m name "value"

setx -m 永久追加環境變量

setx -m name "%name%;value"

設置完之後需要重新打開一個命令行窗口才能看到效果,從此就不用

再圖形界面一步步點擊了,b格瞬間提高,哈哈

2)windows下安裝rocketmq

參考:https://www.jianshu.com/p/4a275e779afa

問題:broker關閉之後,啓動不了了,需要把

c:/user/你的用戶名/裏面的store裏面的所有文件全部刪除,再啓動,就成功了

windows下rocketmq常用命令

start mqnamesrv.cmd   啓動NAMESERVER

啓動BROKER

start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true

啓動編譯好的控制檯界面

java -jar rocketmq-console-ng-1.0.0.jar

關閉broker

mqshutdown.cmd  mqbroker

關閉NAMESERVER

mqshutdown.cmd  mqnamesrv

在自己的筆記本電腦上成功啓動了,cmd窗口成功啓動了namesrv,broker,但是在發送消息時候,出錯了,

Caused by: org.apache.rocketmq.client.exception.MQBrokerException: CODE: 14  DESC: service not available now, maybe disk full, CL:  0.98 CQ: -1.00 INDEX: -1.00, maybe your broker machine memory too small.
 倒騰一番,可能是電腦的內存和硬盤空間不滿足運行要求,需修改rocketmq jvm參數和自定義文件路徑

在bin目錄中的runserver.cmd runbroler.cmd中修改jvm的參數

rocketmq自定義文件路徑 參考

http://www.mamicode.com/info-detail-1469937.html

4)maven依賴問題排查方法:

  • 檢查是否MAVEN依賴衝突
  • 檢查是否MAVEN依賴重複
    • mvn -X compile dependency:tree -Dverbose >a.log
    • 查看文件中是否有 conflict 標記的JAR包依賴
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章