activemq
Java開發的,在內嵌到項目中比較方便
單機吞吐量萬級
可以做主從、高可用
可能丟消息
官方維護已經很少
Rabbitmq(非分佈式)(支持消息的事務)
在rabbitmq中創建幾萬的topic是很容易的,所以可以做到每個硬件訂閱不同的topic
而kafka的topic在分佈式情況下需要同步到其他broker,還需要經過zookeeper
rabbitmq可以通過java程序中調用declareExchange、declareQueue、declareQueue來實現mq的創建
吞吐量到萬級,單機幾萬
Erlang開發,延時很低
有管理界面,適合中小企業管理
社區活躍
國內公司用的多
但,erlang定製開發難度大
在普通集羣模式(不是高可用的),元數據是多份的,但是queue數據只有一份,
優點:可以提高吞吐量
缺點:
1、內部大量數據傳輸
2、只有一份數據,可靠性是沒有保證的
鏡像集羣模式(是高可用的),每個節點都有完整的一份數據
不是分佈式的,一個節點上有一份完整的數據,容量達到該機器的容量無法容納,就掛掉了
Rabbitmq保證數據不丟的方案
生產者confirm模式:開啓發送方確認模式:channel.confirmSelect();
//普通confirm模式:channel.waitForConfirms()
異步confirm模式:
生產者發送消息後,rabbitmq收到消息後會回調生產者,需要提供一個正常回調一個失敗回調:addConfirmListener(handleAck和handleNack)
異步confirm模式中,通過deliveryTag區分是哪條消息
消費者關閉autoAck模式:
消費者ack刪掉消息,消費者nack把消息放回隊列
可以開啓持久化,未持久化的數據可能丟失
RocketMQ
單機吞吐量上十萬
Topic可以有很多
分佈式架構
可靠性高
國內的公司開發,萬一rocketmq被阿里拋棄,那項目就廢了
如果在大型公司,可以投入一組java高級開發研究rocketmq,進行定製開發
Kafka
如果有集羣要求,那kafka當仁不讓
如果個別Topic消息量非常大,kafka當仁不讓(因爲rabbitmq和activemq不好解決)
10萬級別
Topic從幾十個到幾百個的時候吞吐量會急劇下降
極低的延時
消息可能被重複消費
最好不要太多的topic
一個partition一個消費者
適合於大數據方面、實時計算、日誌處理
分佈式:一個topic的每條數據存放在不同的partition上,partition在不同的機器上
0.8版本以後提供副本機制,會選舉leader和follower,需要設置副本的數量,類似HadoopFS
Zookeeper中記錄partition中的offset,消費者消費完不直接提交,而是定時定期提交
高可用:
生產者配置acks=all(spring.kafka.producer.acks=all),確保所有broker中數據都已寫成功後返回,retries=MAX無限次重試
消費者關閉自動提交offset(enable.auto.commit 改成 false )spring.kafka.consumer.enable-auto-commit=false
consumer.commitSync();
@KafkaListener方法中通過Acknowledgment ack注入ack的操作類
通過ack.acknowledge()手動提交偏移量
中小型推薦用RabbitMq
中大型推薦用RocketMq
大數據kafka
MQ的作用
1、解耦:A調用BCD,原來:增加EF調用、減少CD調用都要修改A,而通過MQ後只要增加一個訂閱者、去掉一個訂閱者既可
2、提高響應速度:數據發往mq後立即返回,後續程序再處理數據
3、削峯、容峯:緩衝突然來的幾萬個請求
MQ的副作用
系統可用性會降低
系統複雜性會更高
插入兩條數據問題(可以在mq之前通過雪花算法的唯一鍵解決重複消費問題)
每次重啓消費者,可能導致多次消費
建議在生產者端使用雪花算法產生唯一鍵,消費者端用insert or update方法保存數據