您好,登錄后才能下訂單哦!
好久沒更新博客,之前對MQ有過研究,現(xiàn)在打算系統(tǒng)的研究下消息隊列。
一、 簡介
1、 是一種跨進程的通信機制,用于上下游傳遞消息。
MQ是一種非常常見的上下游“邏輯解耦+物理解耦”的消息通信服務(wù)。
消息發(fā)送上游-》 MQ -》消息發(fā)送下游。 此情況使用MQ
調(diào)用上游-》被調(diào)用下游。 此情況不使用MQ。
優(yōu)點與不足:
2、 不足:
1) 系統(tǒng)更復(fù)雜,多了一個MQ組件。
2) 通信時間更長,消息傳遞路徑增長,延時會增加。
3) 消息的可靠性和不重復(fù)性不能保證。消息不丟不重難以同時保證。
4) 上游無法知道下游的執(zhí)行結(jié)果。如登錄,上游無法知道是否登錄成功。這種情況使用調(diào)用關(guān)系。
一、 使用場景
如定時任務(wù)。按照執(zhí)行順序執(zhí)行。task1,task2,task3。1-2-3的執(zhí)行順序??梢允褂肕Q進行解耦。1為發(fā)布者,2為訂閱者和發(fā)布者,3為訂閱者。
如按照cron執(zhí)行,需預(yù)留時間。有時間浪費。如采用MQ,執(zhí)行順序和執(zhí)行時間得到保證。task1的執(zhí)行時間改變,2、3不需要改變。
1、什么時候不使用MQ?
上游實時關(guān)注執(zhí)行結(jié)果
2、什么時候使用MQ?
1)數(shù)據(jù)驅(qū)動的任務(wù)依賴
2)上游不關(guān)心多下游執(zhí)行結(jié)果
3)異步返回執(zhí)行時間長
二、 MQ分類
RabbitMQ:
對路由(Routing),負載均衡(Load balance)或者數(shù)據(jù)持久化都有很好的支持。
Redis
入隊時,當數(shù)據(jù)比較小時Redis的性能要高于RabbitMQ,而如果數(shù)據(jù)大小超過了10K,Redis則慢的無法忍受;出隊時,無論數(shù)據(jù)大小,Redis都表現(xiàn)出非常好的性能,而RabbitMQ的出隊性能則遠低于Redis。
ZeroMQ
號稱最快的消息隊列系統(tǒng),尤其針對大吞吐量的需求場景。ZMQ能夠?qū)崿F(xiàn)RabbitMQ不擅長的高級/復(fù)雜的隊列,但是開發(fā)人員需要自己組合多種技術(shù)框架,技術(shù)上的復(fù)雜度是對這MQ能夠應(yīng)用成功的挑戰(zhàn)。ZeroMQ具有一個獨特的非中間件的模式,你不需要安裝和運行一個消息服務(wù)器或中間件,因為你的應(yīng)用程序?qū)缪萘诉@個服務(wù)角色。你只需要簡單的引用ZeroMQ程序庫,可以使用NuGet安裝,然后你就可以愉快的在應(yīng)用程序之間發(fā)送消息了。但是ZeroMQ僅提供非持久性的隊列,也就是說如果down機,數(shù)據(jù)將會丟失。其中,Twitter的Storm中使用ZeroMQ作為數(shù)據(jù)流的傳輸。
ActiveMQ
是Apache下的一個子項目。 類似于ZeroMQ,它能夠以代理人和點對點的技術(shù)實現(xiàn)隊列。同時類似于RabbitMQ,它少量代碼就可以高效地實現(xiàn)高級應(yīng)用場景。RabbitMQ、ZeroMQ、ActiveMQ均支持常用的多種語言客戶端 C++、Java、.Net,、Python、 Php、 Ruby等。
Kafka
Kafka是Apache下的一個子項目,是一個高性能跨語言分布式Publish/Subscribe消息隊列系統(tǒng),而Jafka是在Kafka之上孵化而來的,即Kafka的一個升級版。具有以下特性:快速持久化,可以在O(1)的系統(tǒng)開銷下進行消息持久化;高吞吐,在一臺普通的服務(wù)器上既可以達到10W/s的吞吐速率;完全的分布式系統(tǒng),Broker、Producer、Consumer都原生自動支持分布式,自動實現(xiàn)復(fù)雜均衡;支持Hadoop數(shù)據(jù)并行加載,對于像Hadoop的一樣的日志數(shù)據(jù)和離線分析系統(tǒng),但又要求實時處理的限制,這是一個可行的解決方案。Kafka通過Hadoop的并行加載機制來統(tǒng)一了在線和離線的消息處理,這一點也是本課題所研究系統(tǒng)所看重的。Apache Kafka相對于ActiveMQ是一個非常輕量級的消息系統(tǒng),除了性能非常好之外,還是一個工作良好的分布式系統(tǒng)
RocketMQ
阿里巴巴自主研發(fā)。
三、 推送類型
場景1:單發(fā)送單接收
使用場景:簡單的發(fā)送與接收,沒有特別的處理。
場景2:單發(fā)送多接收
使用場景:一個發(fā)送端,多個接收端,如分布式的任務(wù)派發(fā)。為了保證消息發(fā)送的可靠性,不丟失消息,使消息持久化了。同時為了防止接收端在處理消息時down掉,只有在消息處理完成后才發(fā)送ack消息。
場景3:Publish/Subscribe
使用場景:發(fā)布、訂閱模式,發(fā)送端發(fā)送廣播消息,多個接收端接收。
場景4:Routing (按路線發(fā)送接收)
使用場景:發(fā)送端按routing key發(fā)送消息,不同的接收端按不同的routing key接收消息。
場景5:Topics (按topic發(fā)送接收)
使用場景:發(fā)送端不只按固定的routing key發(fā)送消息,而是按字符串“匹配”發(fā)送,接收端同樣如此。
四、 數(shù)據(jù)準確性
1) 可達性:
消息分為上下半場:上半場,發(fā)送方將消息發(fā)送給MQ。下半場,MQ將消息發(fā)送給接收方。
上下半場都有可能出現(xiàn)消息的丟失。為了避免這種情況,需要進行MQ的超時和重傳。
上半場的超時和重傳
MQ上半場如果丟失或者超時,MQ-client-sender內(nèi)的timer會重發(fā)消息,直到期望收到3,如果重傳N次后還未收到,則SendCallback回調(diào)發(fā)送失敗,需要注意的是,這個過程中MQ-server可能會收到同一條消息的多次重發(fā)。
下半場的超時與重傳
MQ下半場如果丟失或者超時,MQ-server內(nèi)的timer會重發(fā)消息,直到成功執(zhí)行,這個過程可能會重發(fā)很多次消息,一般采用指數(shù)退避的策略,先隔x秒重發(fā),2x秒重發(fā),4x秒重發(fā),以此類推,需要注意的是,這個過程中MQ-client-receiver也可能會收到同一條消息的多次重發(fā)。
MQ-client與MQ-server如何進行消息去重,如何進行架構(gòu)冪等性設(shè)計
2) 冪等性
上半場:
1,發(fā)送端MQ-client將消息發(fā)給服務(wù)端MQ-server
2,服務(wù)端MQ-server將消息落地
3,服務(wù)端MQ-server回ACK給發(fā)送端MQ-client
如果3丟失,發(fā)送端MQ-client超時后會重發(fā)消息,可能導(dǎo)致服務(wù)端MQ-server收到重復(fù)消息。
此時重發(fā)是MQ-client發(fā)起的,消息的處理是MQ-server,為了避免步驟2落地重復(fù)的消息,對每條消息,MQ系統(tǒng)內(nèi)部必須生成一個inner-msg-id,作為去重和冪等的依據(jù),這個內(nèi)部消息ID的特性是:
(1)全局唯一
(2)MQ生成,具備業(yè)務(wù)無關(guān)性,對消息發(fā)送方和消息接收方屏蔽
有了這個inner-msg-id,就能保證上半場重發(fā),也只有1條消息落到MQ-server的DB中,實現(xiàn)上半場冪等。
下半場:
4,服務(wù)端MQ-server將消息發(fā)給接收端MQ-client
5,接收端MQ-client回ACK給服務(wù)端
6,服務(wù)端MQ-server將落地消息刪除
需要強調(diào)的是,接收端MQ-client回ACK給服務(wù)端MQ-server,是消息消費業(yè)務(wù)方的主動調(diào)用行為,不能由MQ-client自動發(fā)起,因為MQ系統(tǒng)不知道消費方什么時候真正消費成功。
如果5丟失,服務(wù)端MQ-server超時后會重發(fā)消息,可能導(dǎo)致MQ-client收到重復(fù)的消息。
此時重發(fā)是MQ-server發(fā)起的,消息的處理是消息消費業(yè)務(wù)方,消息重發(fā)勢必導(dǎo)致業(yè)務(wù)方重復(fù)消費(上例中的一次付款,重復(fù)發(fā)卡),為了保證業(yè)務(wù)冪等性,業(yè)務(wù)消息體中,必須有一個biz-id,作為去重和冪等的依據(jù),這個業(yè)務(wù)ID的特性是:
(1)對于同一個業(yè)務(wù)場景,全局唯一
(2)由業(yè)務(wù)消息發(fā)送方生成,業(yè)務(wù)相關(guān),對MQ透明
(3)由業(yè)務(wù)消息消費方負責(zé)判重,以保證冪等
最常見的業(yè)務(wù)ID有:支付ID,訂單ID,帖子ID等。
具體到支付購卡場景,發(fā)送方必須將支付ID放到消息體中,消費方必須對同一個支付ID進行判重,保證購卡的冪等。
有了這個業(yè)務(wù)ID,才能夠保證下半場消息消費業(yè)務(wù)方即使收到重復(fù)消息,也只有1條消息被消費,保證了冪等。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。