RabbitMQ的使用(二)work模式

昨天通宵上线代码,白天睡了一天,下午7.00才醒,做个饭继续学习。

RabbitMQ的使用(二)work模式_第1张图片

接着上文最普通的队列一个生产者推送,一个消费者消费,如果一个生产者有多个消费者那会是什么样呢。

今天我用一个for循环生产50个消息来让消费者消费

package com.hc.work;

import com.hc.mqutil.MqUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

public class Product {

	private static final String QUEUE_NAME="Work_Queue";
	public static void main(String[] args) throws Exception {
		//获取MQ和消息队列
		Connection connection=MqUtil.getConnection();
		Channel channel=connection.createChannel();
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		for(int i=0;i<50;i++){
			String message="我是第"+i+"条消息";
		    channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
		    System.out.println(message);
		    Thread.sleep(i*10);
		}
		channel.close();
		connection.close();
	}
	
}

消费者一二的代码相似

package com.hc.work;

import com.hc.mqutil.MqUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;

public class Consumer1 {

	private static final String QUEUE_NAME="Work_Queue";
	public static void main(String[] args) throws Exception {
		//获得连接--创建通道--声明队列
		Connection connection=MqUtil.getConnection();
		Channel channel=connection.createChannel();
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		 // 同一时刻服务器只会发一条消息给消费者
       // channel.basicQos(1);
        QueueingConsumer consumer=new QueueingConsumer(channel);
     // 监听队列,   autoAck如果为true则为自动完成接收状态,不需要后续的处理,false手动返回完成状态
        channel.basicConsume(QUEUE_NAME, false, consumer);
      //channel.basicConsume(queue, autoAck, callback);
        while(true){
        	
        	QueueingConsumer.Delivery delivery=consumer.nextDelivery();
        	String message=new String(delivery.getBody());
        	System.out.println(" [x] Received '" + message + "'");
        	// 休眠1秒
            Thread.sleep(1000);
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        }
	}
}

消费者2

package com.hc.work;

import com.hc.mqutil.MqUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;

public class Consumer2 {
	private static final String QUEUE_NAME="Work_Queue";
	public static void main(String[] args) throws Exception {
		//获得连接--创建通道--声明队列
		Connection connection=MqUtil.getConnection();
		Channel channel=connection.createChannel();
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		 // 同一时刻服务器只会发一条消息给消费者
        channel.basicQos(1);
        QueueingConsumer consumer=new QueueingConsumer(channel);
     // 监听队列,   autoAck如果为true则为自动完成接收状态,不需要后续的处理,false手动返回完成状态
        channel.basicConsume(QUEUE_NAME, false, consumer);
      //channel.basicConsume(queue, autoAck, callback);
        while(true){
        	
        	QueueingConsumer.Delivery delivery=consumer.nextDelivery();
        	String message=new String(delivery.getBody());
        	System.out.println(" [x] Received '" + message + "'");
        	// 休眠0.01秒
            Thread.sleep(10);
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        }
	}
}

     在我们注释掉channel.basicQos(1);时

     我们启动生产者和消费者,发现一个消费者获取到的为奇数。另一个为偶数,刚好一人一半,但是2休眠的为0.1秒,1休眠的时1秒,这显然不合理

     打开channel.basicQos(1),这时再测试我们发现2获取的明显比1多,这个方法保证了 同一时刻服务器只会发一条消息给消费者。

       channel.basicConsume(queue, autoAck, callback);昨天我们第二个参数填的是true,  只要消息从队列中获取,无论消费者获取到消息后是否成功消息,都认为是消息已经成功消费。

       false为手动确认 消费者从队列中获取消息后,服务器会将该消息标记为不可用状态,等待消费者的反馈,如果消费者一直没有反馈,那么该消息将一直处于不可用状态。代码注释仔细,可以自己测试实际效果。


RabbitMQ的使用(二)work模式_第2张图片

你可能感兴趣的:(RabbitMQ的使用(二)work模式)