訊息中介軟體RabbitMQ系列,多個消費者的時候,不使用預設的輪詢,要實現能者多勞(八)
之前我們已經實現了一個傳送者將訊息傳送到佇列,有多個消費者從佇列裡面拿資料,但是這樣多個消費者是輪詢的方式從佇列裡面拿資料的,每一個消費者拿到的資料都一樣多,現在我們想要實現的是能者多勞,咋實現這個呢?
什麼是訊息確認機制
rabbitmq軟體為什麼 預設是輪詢的了,這個和軟體的訊息確認機制有一定的關係,那麼什麼是訊息確認機制了?
我們先看消費者端的程式碼
public class Customer1 {
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = RabbitMqUtils.getConnection();
// 建立通道
Channel channel = connection.createChannel();
// 讓通道和訊息佇列進行繫結
channel.queueDeclare("work",false,false,false,null);
//接受訊息
channel.basicConsume("work",true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消費者1==="+new String(body));
}
});
}
}
channel.basicConsume("work",true,new DefaultConsumer(channel)
第一個引數的意思: 要接受哪個佇列裡面的訊息
第二個引數:訊息確認機制 true false
第三個引數: 接受訊息後的回撥函式,在這個回撥函式裡面拿出佇列裡面的資料
當第二個引數為true的時候,一個消費者從訊息佇列裡面拿出一個訊息,這個訊息佇列就將佇列裡面的這個訊息刪除,訊息佇列是不管這個消費者拿這個訊息幹什麼,也不管這個訊息執行完沒有,意思就是隻要這個消費者拿了訊息佇列裡面的一個訊息,那麼訊息佇列就刪除佇列中的資訊。
現在我們的問題
現在我們使用預設的訊息確認機制,當一個佇列裡面有10個訊息,現在有兩個消費者,那麼如果是預設的,那麼每一個消費者可以拿到5個訊息,但是現在就有一個問題,如果消費者A拿到5個訊息,在執行第2個 的時候,這個消費者當機了,那麼其他的3個訊息咋辦,那就丟失了啊,訊息佇列只要將訊息給了消費者,那麼訊息佇列裡面的資訊就刪除了,現在消費者A也當機了,其他的3個訊息咋辦,現在我們想要做的就是將這還沒有處理的3個資訊給了消費者B ,讓消費者B 進行處理,實現能者多勞。
解決問題
1 不使用預設的訊息確認機制
channel.basicConsume("work",false,new DefaultConsumer(channel){
第二個引數只要變為false,那麼就不會使用預設的確認機制了。
即使我們的消費者已經將訊息消費了,但是也不會自動的告訴佇列,我已經消費了。
2 設定一個通道里面只是放一個訊息
意思就是 一個消費者在一個通道里面只能消費一個訊息,
所以,我們要告訴我們的通道,一次只能消費一個訊息
原始碼:
Connection connection = RabbitMqUtils.getConnection();
// 建立通道
Channel channel = connection.createChannel();
channel.basicQos(1);
// 讓通道和訊息佇列進行繫結
解釋原始碼新增的一句話
channel.basicQos(1);這個的意思是告訴通道,一次只能消費一個訊息
讓通道和訊息佇列進行繫結
channel.queueDeclare("work",false,false,false,null);
channel.basicConsume("work",false,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消費者1==="+new String(body));
channel.basicAck(envelope.getDeliveryTag(),true);
}
});
channel.basicAck(envelope.getDeliveryTag(),false); 手動確認訊息
相關文章
- RabbitMQ多消費者順序性消費訊息實現MQ
- 訊息中介軟體—RocketMQ訊息消費(三)(訊息消費重試)MQ
- 訊息中介軟體rabbitMQMQ
- 使用訊息中介軟體時,如何保證訊息僅僅被消費一次?
- 訊息中介軟體客戶端消費控制實踐客戶端
- 解析訊息中介軟體之RabbitMQMQ
- 訊息中介軟體消費到的訊息處理失敗怎麼辦?
- 訊息型中介軟體之RabbitMQ基礎使用MQ
- 事件訊息生產消費中介軟體-OSS.DataFlow事件
- 訊息中介軟體RabbitMQ_RabbitMQ快速入門3MQ
- 訊息中介軟體RabbitMQ_RabbitMQ叢集搭建8MQ
- C#中的訊息中介軟體(RabbitMQ 和 Redis)C#MQRedis
- 訊號量實現生產者消費者(程式碼邏輯有問題,不適合多個消費者,不常用)
- Kafka、RabbitMQ、RocketMQ訊息中介軟體的對比 —— 訊息傳送效能KafkaMQ
- kafka消費者消費訊息的流程Kafka
- 分散式系統訊息中介軟體——RabbitMQ的使用進階篇分散式MQ
- 訊息型中介軟體之RabbitMQ叢集MQ
- 訊息中介軟體(RabbitMq、Kafka)分析比較MQKafka
- Java多執行緒消費訊息Java執行緒
- 第四十二章: 基於SpringBoot & RabbitMQ完成DirectExchange分散式訊息多消費者消費Spring BootMQ分散式
- 從訊息中介軟體看分散式系統的多種套路分散式
- [分散式][訊息中介軟體]訊息中介軟體如何實現每秒幾十萬的高併發寫入分散式
- 使用slice和條件變數實現一個簡單的多生產者多消費者佇列變數佇列
- 訊息中介軟體及其測試要點
- 如何設計一個簡單的訊息中介軟體
- 訊息中介軟體—Kafka 的設計思想Kafka
- 不依賴 Spring,你會如何自實現 RabbitMQ 訊息的消費(一)SpringMQ
- 多使用者廣告輪播的實現 (轉)
- vivo 訊息中介軟體測試環境專案多版本實踐
- 訊息中介軟體
- 訊息中介軟體 — 使用場景
- springboot使用RabbitMQ的fanout廣播模式消費者死活接收不到訊息Spring BootMQ模式
- 中介軟體之訊息中介軟體-pulsar
- MQ系列:訊息中介軟體執行原理MQ
- ActiveMQ第六彈:設定多個並行的消費者MQ並行
- RabbitMQ實現延時訊息的兩種方法MQ
- MQ系列2:訊息中介軟體的技術選型MQ
- 使用SpringCloud Stream結合rabbitMQ實現訊息消費失敗重發機制SpringGCCloudMQ