RabbitMQ

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

RocketMQ

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

Kafka

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

ActiveMQ

Java開發(fā),簡單,穩(wěn)定,性能不如前面三個。小項目可以選擇。


RocketMq組成部分有哪些?

Nameserver

無狀態(tài),動態(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)

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

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

廣播消費(fèi)

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


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

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

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

解決方案

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

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

c.redis:使用分布式鎖


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

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

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


RocketMQ如何保證消息不丟失?

producer端

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


broker端

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

集群部署


Consumer端

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


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

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

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

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

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

5、如果錯過了(可能因為網(wǎng)絡(luò)異常、生產(chǎn)者突然宕機(jī)等導(dǎo)致的異常情況)提交/回滾消息,則MQ服務(wù)器將向同一組中的每個生產(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)行過二次確認(rèn)的half消息)的消息將投遞給消費(fèi)者進(jìn)行消費(fèi)。

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

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

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

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


RocketMQ的消息堆積如何處理?

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

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