2-RabbitMQ的工作队列

本文详细介绍了RabbitMQ的工作队列,包括消息应答机制确保消息不丢失,消息公平派遣实现任务均匀分配,以及消息持久性保证服务重启后队列和消息依然存在。通过示例代码展示了如何设置和使用这些特性。
摘要由CSDN通过智能技术生成

RabbitMQ的工作队列

在上一个教程中,我们编写了程序来发送和接收来自命名队列的消息。在这一个中,我们将创建一个工作队列,用于在多个工作人员之间分配耗时的任务。


本次主要介绍的是队列的消息应答、消息公平派遣、消息持久性。

1      消息应答

在我们从队列中取出消息执行任务的时候,可能需要几秒,我们可能会有疑问,如果在我们还在处理这个消息的时候,我们是如何处理的?或者是当消费者取得队列中的消息,队列就把这个消息给删除了,但是如果消费者在取完消息执行任务的时候失败了,那么这个消息也就丢失了;但是实际我们是希望如果如果执行任务的消费者失败了,另外一个消费者还可以继续获得这个消息去执行任务。为了确保消息不被丢失,RabbitMQ支持消息应答。当消费者获得消息任务成功执行后,告诉RabbitMQ,这个消息没用了,可以删除了;RabbitMQ收到消费者应答后,再删除队列中的消息。

如果消费者死机(其通道关闭,连接关闭或TCP连接丢失),而不发送确认信息(不应答),RabbitMQ将会明白消息未被完全处理并重新排队。如果同时有其他消费者在线,则会迅速将其重新提供给另一个消费者。这样就可以确保没有消息丢失,即使工作人员偶尔也会死亡。

消息应答主要是消费者服务中设置,在消费者指定消费队列的时候,打开手动应答机制

      // 消费者指定消费队列,打开应答机制,注意false才是打开手动应对,true为自动应答

      boolean ack =false;

      channel.basicConsume(QUEUE_NAME, ack, consumer);

1.1  消费者完整代码如下

package MQ.WorkQueues.Response;

 

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;

import com.rabbitmq.client.QueueingConsumer;

@SuppressWarnings("deprecation")

/**

 * @Title: MQ.WorkQueues.Worker.java

 * @Package MQ.WorkQueues

 * @Description:TODO(模拟MQ接收队列消息后手动应答,持久性)

 * @Copyright: Copyright (c) 2017 YUANH All Rights Reserved

 * @authoryuanh

 * @date 2017-5-10下午3:48:59

 */

public classWorkerResponse {

   private final static String QUEUE_NAME ="hello";

 

   public static void main(String[] argv)throws Exception {

 

      // 创建连接连接到MabbitMQ

      ConnectionFactoryfactory = newConnectionFactory();

      // 设置MabbitMQ所在主机ip或者主机名

      factory.setHost("127.0.0.1");

      factory.setUsername("yuanh");

      factory.setPassword("yuanh");

      factory.setPort(5672);

      factory.setVirtualHost("y_yuanh");

      Connectionconnection = factory.newConnection();

      Channelchannel = connection.createChannel();

 

      channel.queueDeclare(QUEUE_NAME,false, false,false, null);

      System.out.println(" [*]接收消息等待中,推出请按 CTRL+C");

      QueueingConsumerconsumer = newQueueingConsumer(channel);

      // 消费者指定消费队列,打开应答机制,注意false才是打开手动应对,true为自动应答

      boolean ack =false;

      channel.basicConsume(QUEUE_NAME, ack, consumer);

      try {

         while (true) {

            QueueingConsumer.Deliverydelivery = consumer.nextDelivery();

            Stringmessage = newString(delivery.getBody());

            System.out.println("接收 '" + message +"'");

            try {

                doWork(message);

            }finally{

                System.out.println("结束");

                // 另外需要在每次处理完成一个消息后,手动发送一次应答(ack=false)

                channel.basicAck(delivery.getEnvelope().getDeliveryTag(),

                     

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值