RabbitMQ

erlang開(kāi)發(fā),對(duì)消息堆積的支持并不好,當(dāng)大量消息積壓的時(shí)候,會(huì)導(dǎo)致RabbitMQ的性能急劇下降。每秒鐘可以處理幾萬(wàn)到十幾萬(wàn)條消息。

RocketMQ

Java開(kāi)發(fā),面向??互聯(lián)網(wǎng)集群化??,功能豐富,對(duì)在線業(yè)務(wù)的響應(yīng)時(shí)延做了很多的優(yōu)化,大多數(shù)情況下可以做到毫秒級(jí)的響應(yīng),每秒鐘大概能處理幾十萬(wàn)條消息。

Kafka

Scala開(kāi)發(fā),面向??日志??,功能豐富,性能最高。當(dāng)你的業(yè)務(wù)場(chǎng)景中,每秒鐘消息數(shù)量沒(méi)有那么多的時(shí)候,Kafka 的時(shí)延反而會(huì)比較高。所以,Kafka 不太適合在線業(yè)務(wù)場(chǎng)景。

ActiveMQ

Java開(kāi)發(fā),簡(jiǎn)單,穩(wěn)定,性能不如前面三個(gè)。小項(xiàng)目可以選擇。


RocketMq組成部分有哪些?

Nameserver

無(wú)狀態(tài),動(dòng)態(tài)列表;這也是和zookeeper的重要區(qū)別之一。zookeeper是有狀態(tài)的。

Producer

消息生產(chǎn)者,負(fù)責(zé)發(fā)消息到Broker。

Broker

就是MQ本身,負(fù)責(zé)收發(fā)消息、持久化消息等。

Consumer

消息消費(fèi)者,負(fù)責(zé)從Broker上拉取消息進(jìn)行消費(fèi),消費(fèi)完進(jìn)行ack。


RocketMq消費(fèi)模式有幾種?

集群消費(fèi)

一條消息只會(huì)被同Group中的一個(gè)Consumer消費(fèi)。

多個(gè)Group同時(shí)消費(fèi)一個(gè)Topic時(shí),每個(gè)Group都會(huì)有一個(gè)Consumer消費(fèi)到數(shù)據(jù)

廣播消費(fèi)

消息將對(duì)一個(gè)Consumer Group下的各個(gè)Consumer實(shí)例都消費(fèi)一遍。即使這些Consumber屬于同一個(gè)Consumer Group,消息也會(huì)被Consumer Group中的每個(gè)Consumer都消費(fèi)一次。


消費(fèi)重復(fù)消費(fèi)如何解決?

出現(xiàn)原因:正常情況下在在consumer真正消費(fèi)完消息后應(yīng)該發(fā)送ack,通知broker該消息已正常消費(fèi),從queue中刪除。當(dāng)ack因?yàn)榫W(wǎng)絡(luò)原因無(wú)法發(fā)送到broker,broker會(huì)認(rèn)為詞條消息沒(méi)有被消費(fèi),此后會(huì)開(kāi)啟消息重投機(jī)制把消息再次投遞到consumer。

消費(fèi)模式:在CLUSTERING模式下,消息在broker中會(huì)保證相同group的consumer消費(fèi)一次,但是針對(duì)不同的group的consumer會(huì)推送多次。

解決方案

a.數(shù)據(jù)庫(kù)表:處理消息前,使用消息主鍵在表中帶有約束的字段中insert

b.map:單機(jī)時(shí)可以使用map做限制,消費(fèi)時(shí)查詢當(dāng)前消息id是不是已經(jīng)存在

c.redis:使用分布式鎖


rocketmq如何保證消息的順序消費(fèi)?

首先多個(gè)queue只能保證單個(gè)queue里的順序,queue是典型的FIFO,天然順序。多個(gè)queue同時(shí)消費(fèi)是無(wú)法絕對(duì)保證消息的有序性的。

可以使用同一個(gè)topic,同一個(gè)QUEUE,發(fā)消息的時(shí)候一個(gè)線程去發(fā)送消息,消費(fèi)的時(shí)候一個(gè)線程去消費(fèi)一個(gè)queue里的消息。


RocketMQ如何保證消息不丟失?

producer端

采用send()同步發(fā)消息,發(fā)送結(jié)果是同步感知的。發(fā)送失敗后可以重試,設(shè)置重試次數(shù)。默認(rèn)3次。


broker端

修改刷盤(pán)策略為同步刷盤(pán)。默認(rèn)情況下是異步刷盤(pán)的。

集群部署


Consumer端

完全消費(fèi)正常后在進(jìn)行手動(dòng)ack確認(rèn)。


RocketMq如何實(shí)現(xiàn)分布式事務(wù)?

1、生產(chǎn)者向MQ服務(wù)器發(fā)送half消息。

2、half消息發(fā)送成功后,MQ服務(wù)器返回確認(rèn)消息給生產(chǎn)者。

3、生產(chǎn)者開(kāi)始執(zhí)行本地事務(wù)。

4、根據(jù)本地事務(wù)執(zhí)行的結(jié)果(UNKNOW、commit、rollback)向MQ server發(fā)送提交或回滾消息。

5、如果錯(cuò)過(guò)了(可能因?yàn)榫W(wǎng)絡(luò)異常、生產(chǎn)者突然宕機(jī)等導(dǎo)致的異常情況)提交/回滾消息,則MQ服務(wù)器將向同一組中的每個(gè)生產(chǎn)者發(fā)送回查消息以獲取事務(wù)狀態(tài)。

6、回查生產(chǎn)者本地事務(wù)狀態(tài)。

7、生產(chǎn)者根據(jù)本地事務(wù)狀態(tài)發(fā)送提交/回滾消息。

8、MQ服務(wù)器將丟棄的回滾的消息,但已提交(進(jìn)行過(guò)二次確認(rèn)的half消息)的消息將投遞給消費(fèi)者進(jìn)行消費(fèi)。

???Half Message??:預(yù)處理消息,當(dāng)broker收到此類(lèi)消息后,會(huì)存儲(chǔ)到??RMQ_SYS_TRANS_HALF_TOPIC??的消息消費(fèi)隊(duì)列中

??檢查事務(wù)狀態(tài)??:Broker會(huì)開(kāi)啟一個(gè)定時(shí)任務(wù),消費(fèi)??RMQ_SYS_TRANS_HALF_TOPIC??隊(duì)列中的消息,每次執(zhí)行任務(wù)會(huì)向消息發(fā)送者確認(rèn)事務(wù)執(zhí)行狀態(tài)(提交、回滾、未知),如果是未知,Broker會(huì)定時(shí)去回調(diào)在重新檢查。

超時(shí):如果超過(guò)回查次數(shù),默認(rèn)回滾消息。

也就是他并未真正進(jìn)入Topic的queue,而是用了臨時(shí)queue來(lái)放所謂的??half message??,等提交事務(wù)后才會(huì)真正的將half message轉(zhuǎn)移到topic下的queue。


RocketMQ的消息堆積如何處理?

?1、如果可以添加消費(fèi)者解決,就添加消費(fèi)者的數(shù)據(jù)量

2、如果出現(xiàn)了queue,但是消費(fèi)者多的情況。可以使用準(zhǔn)備一個(gè)臨時(shí)的topic,同時(shí)創(chuàng)建一些queue,在臨時(shí)創(chuàng)建一個(gè)消費(fèi)者來(lái)把這些消息轉(zhuǎn)移到topic中,讓消費(fèi)者消費(fèi)。