Rocket MQ
零、定義:一個訊息中介軟體,貌似是參考kafaka做的,是面向叢集和大資料的
一、官網
- 由於已經是apache頂級專案了,直接字首加apache.org,http://rocketmq.apache.org/
- 原始碼首頁https://github.com/apache/rocketmq/tree/master/docs/cn
二、部署
- 先看看這個quick starthttp://rocketmq.apache.org/docs/quick-start/
- 我這邊是mac
- 下載原始碼:https://mirrors.bfsu.edu.cn/apache/rocketmq/4.7.1/rocketmq-all-4.7.1-source-release.zip
- 解壓zip檔案
待補:算了,這塊還是用docker 啟 centos來做實驗吧,中午時間不夠用,先缺著
監控後臺部署:https://github.com/apache/rocketmq-externals
三、啟動
- nameserver:無狀態的註冊中心(註冊中心結合微服務的Eureka理解,無狀態是因為name server之間並不通訊,也不保持同步)
-
sh bin/mqnamesrv
-
- broker:理解為微服務中的一個具體服務,可以有多個,多個broker連線nameserver就形成一個叢集
-
# n代表name server的地址,9876是name server的預設埠 sh bin/mqbroker -n localhost:9876
-
四、傳送訊息(Demo程式碼待補)
1、同步訊息:簡單來說就是A給Broker傳送訊息,需要同步收到Broker的回執
2、非同步訊息:簡單來說就是A給Broker傳送訊息,可以非同步收到Broker的回執(通過回撥的方式),相當於n條訊息傳送完之後再來看傳送的結果(這個描述並不嚴謹,但大致邏輯是這樣的)
3、單向訊息:簡單來說就是A給Broker傳送訊息,不需要回執,不管收到沒,反正我發了
4、事務訊息:二階段提交的一種做法,先舉個例子:比如我去接我老婆下班,
場景1、
我:老婆,可以去接你了嗎(傳送一個HAFT Msg,待確認的訊息)
老婆:可以,我今天不加班,可以準時下班(收到Broker的回覆)
我:好的,那我出發了(收到回覆之後執行本地方法)
我:老婆,我到了,你可以下來了(執行完本地方法後,給broker傳送確認提交的訊息)
老婆:那我下來了(broker獲取到本地方法執行的結果後,執行不同的操作,這邊是提交,下面再舉個回滾的例子)
場景2、
我:老婆,可以去接你了嗎(傳送一個HAFT Msg,待確認的訊息)
老婆:可以,我今天不加班,可以準時下班(收到Broker的回覆)
我:好的,那我出發了(收到回覆之後執行本地方法)
我:老婆,我這邊領導臨時安排任務過不去了(本地方法執行失敗後,給broker傳送回滾的訊息)
老婆:那我自己打車回去(broker獲取到本地方法執行的結果後,執行不同的操作,這邊是回滾)
場景3、
我:老婆,可以去接你了嗎(傳送一個HAFT Msg,待確認的訊息)
老婆:可以,我今天不加班,可以準時下班(收到Broker的回覆)
我:好的,那我出發了(收到回覆之後執行本地方法)
我:領導直接過來催任務了,沒時間給老婆回信息(本地方法執行的結果一直沒有發給broker)
老婆:打個電話問一下,怎麼還沒來,還沒人接,等著跪搓衣板吧(事務訊息的回查機制,查詢本地事務的執行情況)
老婆:打了n次還沒人接,算了我自己打車回家(多次查詢不到結果,就放棄,這邊其實也有可能得到的是:老婆,再等等,我也不確定什麼時候可以下班,這種則屬於訊息回覆狀態中的UNKNOW狀態)
場景4、
我:老婆,可以去接你了嗎(傳送一個HAFT Msg,待確認的訊息)
老婆:可以,我今天不加班,可以準時下班(收到Broker的回覆)
我:好的,那我出發了(收到回覆之後執行本地方法)
我:領導直接過來催任務了,沒時間給老婆回信息(本地方法執行的結果一直沒有發給broker)
老婆:打個電話問一下,怎麼還沒來
我:來了來了,剛才領導臨時有個事處理下,還好是個小問題,我三下五除二給解決了,我現在已經到你樓下了
老婆:那我下來了
五、對於事務訊息的思考:
剛學用這個的時候我也很迷糊,這玩意咋用呀?
後面我突然想起來,以前系統裡面用過一個東西。
就是比如我們支付成功,訂單狀態扭轉,要給使用者傳送微信通知。這個時候,是有可能這個支付成功的程式碼提交失敗的,那這個時候可能訊息就傳送出去了。咋辦?
比較直接的做法就是註冊個Commit事務的監聽方法,在事務提交成功之後才傳送訊息,那又衍生另外一個問題:啊,萬一我傳送訊息還沒成功,伺服器掛了怎麼辦
哈哈,我們之前的系統是不管訊息發不傳送成功的,因為覺得不重要,但這裡要是個重要的事務性邏輯,那可不能這麼幹,所以呢,結合剛才的事務性訊息的大致原理和流程,我們改進一下
我在本地方法開始執行前傳送一個預提交的資訊到broker,然後本地方法執行完成之後,給broker傳送確認(如果失敗,則做業務補償方案:自動或人工都可以)。確認完我們幹另外一件事情,如果此時broker一直收不到結果,那麼會觸發回查機制(這個就是一致性的重點了,回查機制確保這個訊息最終會被髮送出去,或者不需要傳送就結束)。
這個流程其實像是TCC的一個流程,或者就是吧,不太確定。
反正經過這個改造,我們可以確認在訂單確認支付成功之後才傳送簡訊,而且也不會因為傳送簡訊的時候伺服器宕機而不再重新發送。
題外話:其實我們之前是直接儲存一個本地事件表,如果提交成功,本地事件表就會有一條記錄,根據這條記錄繼續操作傳送微信通知,哈哈。就是需要另外擴充套件一個本地事件表的機制,還有就是實時性比不上監聽的模式