RabbitMQ的使用(二)work模式

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


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

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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值