MQ(Message Queue)消息隊列
MQ:是一種應用程序對應用程序傳遞消息的中間件,是通過讀寫出入隊列來通信。
三種通訊模式 1.點對點,2.多點廣播,3.發佈和訂閱(一般用這個)
優點:
1.異步:執行失敗重試,提高接口的性能(失效策略;數據回補)
2.解耦:利用MQ降低系統的耦合性(系統重構)
3.削峯:將一些無需及時返回且耗時的操作提取出來,進行異步處理,從而節省服務器的響應時間來提高系統的吞吐量(秒殺,公司的活動:搶金幣)
缺點:
1.MQ一旦掛了,整個系統就奔潰了(高可用)
2.系統的複雜度提高(消息堆積)
3.數據不一致(消息重複,消息順序,消息丟了)
如何選型:RabbitMQ,RocketMQ,Kafka
Kafka是主要用於配合大數據類的系統來進行實時數據計算、日誌採集等場景(主要支持簡單的MQ功能)
我們一般在RabbitMQ和RocketMQ中間來選擇
選擇RocketMQ的理由(阿里出品):
1.topic可以達到幾百,幾千個的級別,吞吐量會有較小幅度的下降(RabbitMQ會大幅下降)
2.分佈式集羣,每個部分都可以水平擴展(RabbitMQ主從集羣)
3.java開發(RabbitMQ用erlang語言開發)
4.吞吐量是10萬級(RabbitMQ是萬級)
缺點:
1.延時毫秒級(RabbitMQ是微秒級)
2.社區活躍度一般(RabbitMQ比較好版本迭代特別快)
MQ的高可用
RabbitMQ是鏡像集羣模式(主從)
Kafka是分佈式集羣(副本集,HA),每個節點都有一個replicate備份。讀寫都在leader節點
RocketMQ是分佈式集羣如下
Name Server:主要提供輕量級查找和路由服務(保存了其它三部分的信息)(各個節點之間不通信)
Broker Cluster:輕量的topic和queue機制(消息的存儲,支持push和pull)
Product Cluster:分佈式的producers通過負載均衡模型向broker發送消息
Consumer Cluster:支持push,pull,支持集羣消費與消息廣播同時提供實時訂閱
MQ的消息冪等性(不重複)
造成的原因:1.系統重啓 2.網絡異常 3.消費失敗
解決方案
- 消息的唯一標識存入redis中並進行判斷
- 數據庫的存儲判斷
MQ丟消息
- producter:發送消息狀態超時或者失敗,則會觸發默認的2次重試(支持日誌的索引查找)
- broker:是一主多從的節點,同時支持同步和異步刷盤的策略,保證消息落到本地內存中,消息也支持持久化到commitlog裏面,即使宕機,未消費的消息也可以加載出來
- consumer:確保拉取到的消息成功消費,consumer自身維護了一個持久化的offset,消費成功後纔會更新自己的offset,offset會持久化到本地,即使consumer掛掉重啓之後可以繼續拉取offset之前的消息到本地
MQ消息的積壓
策略:超出了buffer,也可以丟棄,然後再從CommitLog中補數據
打開rocketmq的控制檯查看是歷史消費記錄,如果是消息寫入速度大於消息的消費速度,調整業務代碼或對消費者進行擴容
Consumer消費消息出現問題,只能操作臨時緊急擴容了,具體操作步驟和思路如下:
1)先修復consumer的問題,確保其恢復消費速度,然後將現有cnosumer都停掉
2)新建一個topic,partition是原來的10倍,臨時建立好原先10倍或者20倍的queue數量
3)然後寫一個臨時的分發數據的consumer程序,這個程序部署上去消費積壓的數據,消費之後不做耗時的處理,直接均勻輪詢寫入臨時建立好的10倍數量的queue
4)接着臨時徵用10倍的機器來部署consumer,每一批consumer消費一個臨時queue的數據
5)這種做法相當於是臨時將queue資源和consumer資源擴大10倍,以正常的10倍速度來消費數據
6)等快速消費完積壓數據之後,得恢復原先部署架構,重新用原先的consumer機器來消費消息
MQ消息的順序
避開這種使用場景