一丽已、mq的特性:
異步蚌堵。上游無法直到下游的執(zhí)行結(jié)果。這是mq無法取代直接調(diào)用最根本的原因。
所以吼畏,很多人說mq削峰督赤,但是不是什么都削,必須是宫仗,調(diào)用方對調(diào)用結(jié)果的及時性不是很在意才行够挂,比如,登錄藕夫,你不可能用mq削峰吧孽糖。。解耦毅贮。A系統(tǒng)發(fā)送個數(shù)據(jù)到BCD三個系統(tǒng)办悟,接口調(diào)用發(fā)送,那如果E系統(tǒng)也要這個數(shù)據(jù)滩褥,或者C系統(tǒng)現(xiàn)在不要這個數(shù)據(jù)病蛉,或者A系統(tǒng)再發(fā)第二種數(shù)據(jù),再或者瑰煎,BCDE這些服務(wù)铺然,一旦掛了,這個數(shù)據(jù)就丟失了酒甸。
總之魄健,耦合性太重,削峰插勤。對于一些上游對下游的直接結(jié)果不是很關(guān)注的業(yè)務(wù)沽瘦,對CAP的C容錯比較大的業(yè)務(wù)。上游并發(fā)大农尖,下游處理能力小析恋,如果上游直接調(diào)用,下游會直接被打死盛卡。那么可以把任務(wù)先放到mq中去助隧,然后異步慢慢處理。
二滑沧、mq的使用場景:
mq只是一個消息隊列喇颁,或者是一個生產(chǎn)者消費者模式,是進程間通信的嚎货。
進程內(nèi)的消費者生產(chǎn)者適合的場景跨服務(wù)就是mq適合的場景橘霎。
比如:
2.1. 時間上有依賴的任務(wù)執(zhí)行。
比如殖属,我曾經(jīng)有一個定時服務(wù)姐叁,同步,小區(qū),人員外潜,房屋等等信息原环,之后還要對這些信息進行統(tǒng)計,計算處理处窥。各個步驟有時間上的依賴嘱吗。
1.1 一種很常見的方式:每個定時任務(wù)開啟定時器,然后同步的時間點預(yù)定在上一個任務(wù)之后滔驾,然后在預(yù)留相當長的時間防止任務(wù)執(zhí)行超時了谒麦。
優(yōu)點:簡單,趕工期先這樣應(yīng)付著哆致。绕德。。
缺點就是:
1摊阀、一旦上一個任務(wù)超時了耻蛇,下一個任務(wù)的數(shù)據(jù)就錯了。
2胞此、需要預(yù)留時間臣咖,時間緊的話沒有那么多時間浪費,比如就晚上有時間給你同步數(shù)據(jù)漱牵,可晚上就那么幾個鐘頭夺蛇。
3、一旦以后數(shù)據(jù)量多了布疙,同步時間延長了,則需要修改同步時間愿卸。
1.2 另一種方式:一個任務(wù)執(zhí)行完了之后灵临,直接調(diào)下一個任務(wù)的方法,執(zhí)行下一個任務(wù)趴荸。
這種方式儒溉,能夠解決第一種方式的3個缺點。
缺點:1发钝、耦合性很高酗捌,一個任務(wù)之后怀薛,要回調(diào)很多個下個任務(wù)的方法,不是很優(yōu)雅。而且分俯,如果以后再新增一個回調(diào)任務(wù),則又要修改上個任務(wù)的回調(diào)方法瞧挤。
2闷沥、假設(shè)這個任務(wù)是在多個服務(wù)的,如果遠程調(diào)用的話,很可能會因為網(wǎng)絡(luò)原因等調(diào)用失敗揉阎,除非引入了rpc有重試機制庄撮。
1.3 再一種方式:寫一個進程內(nèi)的消費者生產(chǎn)者模式。然后上游任務(wù)執(zhí)行完毙籽,直接往進程內(nèi)隊列里put洞斯,然后,下游任務(wù)直接訂閱這個隊列坑赡,然后就會直接得到處理了烙如。
優(yōu)點:耦合性不高。
缺點:需要花時間去寫一個進程內(nèi)消費者生產(chǎn)者模式垮衷。比如這樣的東西:寫一個消費者生產(chǎn)者模式
2.2. 可以異步厅翔,耦合性高,執(zhí)行時間長的場景
比如搀突,添加一個商品刀闷,就要生產(chǎn)一個商品索引,還要生成一個商品的詳情頁仰迁,等等甸昏。
1、如果直接rpc調(diào)用徐许,那么施蜜,直接調(diào)用,則執(zhí)行時間太長雌隅。
2翻默、如果異步線程調(diào)用,耦合性太大恰起,一旦增加一個獲取通知的回調(diào)修械,又要修改生成商品服務(wù)。
3检盼、而且直接調(diào)用肯污,萬一下游服務(wù)掛了,消息就丟失了吨枉。
2.3. 流量削峰
上游qps大蹦渣,直接調(diào)用,會把下游打死貌亭。
比如上游只有簡單的下單邏輯柬唯,下游有計算檢查,扣庫存等等圃庭。自然上游會比下游qps大权逗。
如果可以異步美尸,對執(zhí)行失敗可以容忍:可以把任務(wù)往mq中放,mq如果用主動推的方式斟薇,可以設(shè)置消費者線程數(shù)师坎,慢慢處理。如果用拉的方式堪滨,可以自己慢慢拉取胯陋。
否則,必須要同步調(diào)用的場景:只能服務(wù)限流的方式袱箱,拋棄一部分請求遏乔。
對于削峰
總結(jié):異步,解耦发笔,削峰盟萨。
三、線程池和mq的區(qū)別
1了讨、線程池是進程內(nèi)隊列捻激,也是隊列。
2前计、如果消息積壓多了胞谭,用線程池的方式,會積壓大量任務(wù)男杈,消耗大量內(nèi)存丈屹。
3、消息丟失伶棒,重試機制旺垒,持久化等,應(yīng)答機制肤无,如果消費者系統(tǒng)沒有運行先蒋,則線程池調(diào)用的方式,直接導(dǎo)致舅锄,消息丟失了鞭达。
4司忱、mq的解耦機制是線程池沒有的皇忿。
四、mq的缺點
1坦仍、異步鳍烁,這是最大的缺點。
2繁扎、引入組件幔荒,增加復(fù)雜度糊闽。
五、mq的高可用
activemq可以做主從爹梁。
rabbitmq可以做鏡像集群右犹。
rocketmq和kafka更不用說,比如rocketmq的name server集群姚垃、broker集群念链。
rabbitmq的普通的集群:每個節(jié)點只有元數(shù)據(jù),獲取數(shù)據(jù)的時候积糯,去真正節(jié)點上去拉掂墓,所以做不到高可用,只是負載均衡了一下看成。鏡像集群:則是每個節(jié)點有都有這個數(shù)據(jù)君编。
六、mq 如何保證冪等性
不管是發(fā)送川慌、消費吃嘿,如果網(wǎng)絡(luò)原因,還沒來得及ack應(yīng)答窘游,導(dǎo)致重復(fù)推送唠椭,就會導(dǎo)致重復(fù)消息的問題。
要根據(jù)業(yè)務(wù)來忍饰。
有寫數(shù)據(jù)不需要保證冪等性贪嫂,比如set或update操作。
比如數(shù)據(jù)庫的唯一鍵約束艾蓝,比如訂單id力崇,做一個唯一索引。
如果實在不好保證赢织,只能存一個唯一id亮靴,然后處理前,查一下沒有沒處理過這個id于置。
七茧吊、如何保證消息的可靠性傳輸
比如activemq,消費者設(shè)置應(yīng)答模式為同步模式八毯,這樣搓侄,在服務(wù)端沒有給生產(chǎn)者應(yīng)答之前,生產(chǎn)者一直堵塞话速。生產(chǎn)者設(shè)置消息持久化到硬盤讶踪,消費者設(shè)置手動應(yīng)答模式,當真正消費了消息之后泊交,才應(yīng)答乳讥。
如果是rabbitmq的話:為了保證消息發(fā)布到rabbitmq成功以否柱查,rabbitmq提供了回調(diào)確認機制,保證數(shù)據(jù)不丟失云石,當然事務(wù)也可以做到唉工,但是性能不好,不常用汹忠,也有持久化和應(yīng)答酵紫。
rocketmq也有同步寫主從以及持久化和應(yīng)答機制。
kafka不是很熟:kafka错维,kafka也可以通過配置奖地,參數(shù),必須寫入多少臺機器赋焕,才算寫入成功参歹。
八、如何保證消息的順序性
一個queue對應(yīng)一個消費者隆判,就絕對是有序的犬庇,如果對應(yīng)多個消費者自然就無序。
九侨嘀、消息延遲臭挽、消息積壓怎么處理?
1咬腕、修好consumer欢峰,然后可以臨時增加consumer增加分擔消費能力,比如rabbitmq涨共,rocketmq纽帖,則直接新增消費者就可以。
2举反、如果不好這么做懊直,可以新建一個臨時queue,然后把消息轉(zhuǎn)發(fā)過來火鼻,然后新的queue室囊,用多個消費者消費。
3魁索、如果對于rabbitmq融撞,這種設(shè)置過期時間的,造成消息積壓導(dǎo)致的消息丟失蛾默,則只能想辦法找出丟失的數(shù)據(jù)懦铺,然后捉貌,再推送到mq中去支鸡《睿·