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