rabbitmq学习(3)——work queue工作队列之轮询

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_38322527/article/details/102718988

一、出现背景

在我的前一篇博客中,我们简单说明了simple queue 简单队列的发送和接受操作,但总体看代码和流程,我们会发现存在很多不足。

简单队列存在的不足:
耦合性过高。
1、生产者和消费者必须保证一一对应,如果需要实现多个消费者共同消费同一个消息生产者生产的消息时,则会出问题。(消息一旦消费就没有了)
2、生产者的队列名称发生变更后,消息消费者的队列名也需要同时进行变更操作。

所以,我们今天一起共同学习另外一个消息队列work queue工作队列

二、工作队列的模型

在这里插入图片描述

p:消息生产者
c1、c2:消息消费者
红色的则是消息队列

为什么会出现 work queue 工作队列?

simple queue 是 消息消费者和消息生产者一一对应的关系,在实际开发中,生产者发送消息是毫不费力的,而消费者一般是要跟业务相结合的,消费者收到消息就需要处理。可能需要花费时间,这时候队列中就会积压过多的消息。

三、实现方式

3.1、消息生产者

与上一篇博客的差别也就是命名不同,其次是发了多条消息。

import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import cn.linkpower.util.MqConnectUtil;

public class Send {
	private static final String queue_name = "test_work_queue";
	public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
		//1、建立连接
		Connection mqConnection = MqConnectUtil.getMqConnection();
		//2、建立信道(通道)
		Channel channel = mqConnection.createChannel();
		//3、声明队列
		channel.queueDeclare(queue_name, false, false, false, null);
		
		//4、发送100条消息
		for (int i = 0; i < 50; i++) {
			String string = "hello xiangjiao "+i;
			System.out.println("send msg = "+string);
			//发送消息
			channel.basicPublish("", queue_name, null, string.getBytes());
			//消息发送慢一点
			Thread.sleep(i*20);
		}
		//5、使用完毕后,需要及时的关闭流应用
		channel.close();
		mqConnection.close();
	}
}

3.2、消费者一和消费者二

1、消费者一和二的区别只是在打印数据时,输出不同,一个是msg1,一个是msg2,这里只列出消费者一的代码。
2、消费者二的延迟相比消费者一而言,消费者一为1000ms,消费者二为2000ms。

import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;
import cn.linkpower.util.MqConnectUtil;

public class GetMsg1 {
	private final static String queue_name="test_work_queue";
	public static void main(String[] args) throws IOException, TimeoutException {
		//1、建立连接
		Connection mqConnection = MqConnectUtil.getMqConnection();
		//2、获取信道
		Channel channel = mqConnection.createChannel();
		//3、声明队列
		channel.queueDeclare(queue_name, false, false, false, null);
		//4、信访室接受消息
		DefaultConsumer consumer = new DefaultConsumer(channel){
			@Override
			public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
					throws IOException {
				String message = new String(body, "UTF-8");
				System.out.println(" get msg new1 = " + message );
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}finally {
					System.out.println("get msg new1 done");
				}
			}
		};
		//5、创建监听
		channel.basicConsume(queue_name,true, consumer);
	}
}

四、运行测试

先运行消息消费者一和二,提前创建好监听。
再运行消息生产者代码,观察运行打印信息效果。
消息生产者运行效果
在这里插入图片描述
消息消费者一运行效果
在这里插入图片描述
消息消费者二运行效果
在这里插入图片描述
现象:
1、消费者一延时 1000ms,消费者二延时 2000ms,但消息数一致。
2、效益一为偶数,消息二为基数。
结论:
这种消息机制叫轮询分发,两者的延迟时间并不会影响到获取到的消息数目。
消息消费为分发处理----消息数%2消息数%n

猜你喜欢

转载自blog.csdn.net/qq_38322527/article/details/102718988