3、RabbitMQ-work queues 工作队列
work queues 工作队列
1、模型图:

2、代码实例(轮询分发)
生产者进行生产消息
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.util.ConnectionUtils;
public class Send { private static final String QUEUE_NAME ="test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//获取连接
Connection conn = ConnectionUtils.getConnection(); //获取Channel
Channel channel= conn.createChannel();
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false,null); //连续发送50个消息
for(int i = ; i<=;i++){
String msg = "work" + i;
channel.basicPublish("",QUEUE_NAME, null, msg.getBytes());
Thread.sleep();
}
channel.close();
conn.close();
}
}
消费者1:
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.util.ConnectionUtils;
public class WorkReceive { private static final String QUEUE_NAME ="test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException { Connection conn = ConnectionUtils.getConnection(); Channel channel = conn.createChannel();
//声明队列
channel.queueDeclareNoWait(QUEUE_NAME, false, false, false, null); //定义一个消费者
Consumer consumer = new DefaultConsumer(channel){
//收到消息就会触发这个方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body,"utf-8");
System.out.println("消费者1接收到的消息" + msg); try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
System.out.println("消费者1处理完成!");
}
}
};
//监听队列
boolean autoAck = true;
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}
消费者2:
import java.io.IOException;
import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.util.ConnectionUtils; public class WorkReceive2 { private static final String QUEUE_NAME ="test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException { Connection conn = ConnectionUtils.getConnection(); Channel channel = conn.createChannel();
//声明队列
channel.queueDeclareNoWait(QUEUE_NAME, false, false, false, null); //定义一个消费者
Consumer consumer = new DefaultConsumer(channel){
//收到消息就会触发这个方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body,"utf-8");
System.out.println("消费者2接收到的消息" + msg); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
System.out.println("消费者2处理完成!");
}
}
};
//监听队列
boolean autoAck = true;
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}
提前开启消费者进行对消息队列的监听!!!
消费者2接收到的消息work2
消费者2处理完成!
消费者2接收到的消息work4
消费者2处理完成!
消费者2接收到的消息work6
消费者2处理完成!
消费者2接收到的消息work8
消费者2处理完成!
消费者2接收到的消息work10
消费者2处理完成!
消费者2接收到的消息work12
消费者2处理完成!
消费者2接收到的消息work14
消费者2处理完成!
消费者2接收到的消息work16
消费者2处理完成!
消费者2接收到的消息work18
消费者2处理完成!
消费者2接收到的消息work20
消费者2处理完成!
消费者2接收到的消息work22
消费者2处理完成!
消费者2接收到的消息work24
消费者2处理完成!
消费者2接收到的消息work26
消费者2处理完成!
消费者2接收到的消息work28
消费者2处理完成!
消费者2接收到的消息work30
消费者2处理完成!
消费者2接收到的消息work32
消费者2处理完成!
消费者2接收到的消息work34
消费者2处理完成!
消费者2接收到的消息work36
消费者2处理完成!
消费者2接收到的消息work38
消费者2处理完成!
消费者2接收到的消息work40
消费者2处理完成!
消费者2接收到的消息work42
消费者2处理完成!
消费者2接收到的消息work44
消费者2处理完成!
消费者2接收到的消息work46
消费者2处理完成!
消费者2接收到的消息work48
消费者2处理完成!
消费者2接收到的消息work50
消费者2处理完成!
消费者1:
消费者2接收到的消息work2
消费者2处理完成!
消费者2接收到的消息work4
消费者2处理完成!
消费者2接收到的消息work6
消费者2处理完成!
消费者2接收到的消息work8
消费者2处理完成!
消费者2接收到的消息work10
消费者2处理完成!
消费者2接收到的消息work12
消费者2处理完成!
消费者2接收到的消息work14
消费者2处理完成!
消费者2接收到的消息work16
消费者2处理完成!
消费者2接收到的消息work18
消费者2处理完成!
消费者2接收到的消息work20
消费者2处理完成!
消费者2接收到的消息work22
消费者2处理完成!
消费者2接收到的消息work24
消费者2处理完成!
消费者2接收到的消息work26
消费者2处理完成!
消费者2接收到的消息work28
消费者2处理完成!
消费者2接收到的消息work30
消费者2处理完成!
消费者2接收到的消息work32
消费者2处理完成!
消费者2接收到的消息work34
消费者2处理完成!
消费者2接收到的消息work36
消费者2处理完成!
消费者2接收到的消息work38
消费者2处理完成!
消费者2接收到的消息work40
消费者2处理完成!
消费者2接收到的消息work42
消费者2处理完成!
消费者2接收到的消息work44
消费者2处理完成!
消费者2接收到的消息work46
消费者2处理完成!
消费者2接收到的消息work48
消费者2处理完成!
消费者2接收到的消息work50
消费者2处理完成!
官方文档的解释如下:

3、代码实例(公平派遣/公平分发)Fair dispatch

还有一点需要注意,使用公平分发,必须关闭自动应答,改为手动应答
总结:能者多劳
生产者:
import java.io.IOException;
import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.util.ConnectionUtils; public class Send { private static final String QUEUE_NAME ="test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//获取连接
Connection conn = ConnectionUtils.getConnection(); //获取Channel
Channel channel= conn.createChannel();
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false,null); //每个消费者发送确认消息之前,消费队列不发送下一个消息到消费者,一个只处理一个消息
//限制发送给同一个消费者不得超过一个消息
int prefetchCount = 1;
channel.basicQos(prefetchCount ); //连续发送50个消息
for(int i = ; i<=;i++){
String msg = "work" + i;
channel.basicPublish("",QUEUE_NAME, null, msg.getBytes());
Thread.sleep(i + );
}
channel.close();
conn.close();
} }
消费者1:
import java.io.IOException;
import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.util.ConnectionUtils; public class WorkReceive { private static final String QUEUE_NAME ="test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException { Connection conn = ConnectionUtils.getConnection(); Channel channel = conn.createChannel();
//声明队列
channel.queueDeclareNoWait(QUEUE_NAME, false, false, false, null); //保证一次只分发一次
int prefetchCount = 1;
channel.basicQos(prefetchCount ); //定义一个消费者
Consumer consumer = new DefaultConsumer(channel){
//收到消息就会触发这个方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body,"utf-8");
System.out.println("消费者1接收到的消息" + msg); try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
System.out.println("消费者1处理完成!");
//手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
} }
};
//监听队列
//自动应答false
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME, autoAck, consumer); }
}
消费者2:
import java.io.IOException;
import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.util.ConnectionUtils; public class WorkReceive2 { private static final String QUEUE_NAME ="test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException { Connection conn = ConnectionUtils.getConnection(); Channel channel = conn.createChannel();
//声明队列
channel.queueDeclareNoWait(QUEUE_NAME, false, false, false, null); int prefetchCount = 1;
channel.basicQos(prefetchCount ); //定义一个消费者
Consumer consumer = new DefaultConsumer(channel){
//收到消息就会触发这个方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body,"utf-8");
System.out.println("消费者2接收到的消息" + msg); try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
System.out.println("消费者2处理完成!");
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
//监听队列
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME, autoAck, consumer); }
}
消费者1:
消费者1接收到的消息work1
消费者1处理完成!
消费者1接收到的消息work4
消费者1处理完成!
消费者1接收到的消息work6
消费者1处理完成!
消费者1接收到的消息work9
消费者1处理完成!
消费者1接收到的消息work11
消费者1处理完成!
消费者1接收到的消息work14
消费者1处理完成!
消费者1接收到的消息work16
消费者1处理完成!
消费者1接收到的消息work19
消费者1处理完成!
消费者1接收到的消息work21
消费者1处理完成!
消费者1接收到的消息work24
消费者1处理完成!
消费者1接收到的消息work26
消费者1处理完成!
消费者1接收到的消息work29
消费者1处理完成!
消费者1接收到的消息work31
消费者1处理完成!
消费者1接收到的消息work34
消费者1处理完成!
消费者1接收到的消息work36
消费者1处理完成!
消费者1接收到的消息work39
消费者1处理完成!
消费者1接收到的消息work41
消费者1处理完成!
消费者1接收到的消息work44
消费者1处理完成!
消费者1接收到的消息work46
消费者1处理完成!
消费者1接收到的消息work49
消费者1处理完成!
消费者2:
消费者2接收到的消息work2
消费者2处理完成!
消费者2接收到的消息work3
消费者2处理完成!
消费者2接收到的消息work5
消费者2处理完成!
消费者2接收到的消息work7
消费者2处理完成!
消费者2接收到的消息work8
消费者2处理完成!
消费者2接收到的消息work10
消费者2处理完成!
消费者2接收到的消息work12
消费者2处理完成!
消费者2接收到的消息work13
消费者2处理完成!
消费者2接收到的消息work15
消费者2处理完成!
消费者2接收到的消息work17
消费者2处理完成!
消费者2接收到的消息work18
消费者2处理完成!
消费者2接收到的消息work20
消费者2处理完成!
消费者2接收到的消息work22
消费者2处理完成!
消费者2接收到的消息work23
消费者2处理完成!
消费者2接收到的消息work25
消费者2处理完成!
消费者2接收到的消息work27
消费者2处理完成!
消费者2接收到的消息work28
消费者2处理完成!
消费者2接收到的消息work30
消费者2处理完成!
消费者2接收到的消息work32
消费者2处理完成!
消费者2接收到的消息work33
消费者2处理完成!
消费者2接收到的消息work35
消费者2处理完成!
消费者2接收到的消息work37
消费者2处理完成!
消费者2接收到的消息work38
消费者2处理完成!
消费者2接收到的消息work40
消费者2处理完成!
消费者2接收到的消息work42
消费者2处理完成!
消费者2接收到的消息work43
消费者2处理完成!
消费者2接收到的消息work45
消费者2处理完成!
消费者2接收到的消息work47
消费者2处理完成!
消费者2接收到的消息work48
消费者2处理完成!
消费者2接收到的消息work50
消费者2处理完成!
这时候现象就是消费者 1 速度小于消费者 2
体现一句话:能者多劳

3、RabbitMQ-work queues 工作队列的更多相关文章
- RabbitMQ --- Work Queues(工作队列)
目录 RabbitMQ --- Hello Mr.Tua 前言 Work Queues 即工作队列,它表示一个 Producer 对应多个 Consumer,包括两种分发模式:轮循分发(Round-r ...
- 译:2. RabbitMQ Java Client 之 Work Queues (工作队列)
在上篇揭开RabbitMQ的神秘面纱一文中,我们编写了程序来发送和接收来自命名队列的消息. 本篇我们将创建一个工作队列,工作队列背后的假设是每个任务都交付给一个工作者 本篇是译文,英文原文请移步:ht ...
- rabbitmq消息队列——"工作队列"
二."工作队列" 在第一节中我们发送接收消息直接从队列中进行.这节中我们会创建一个工作队列来分发处理多个工作者中的耗时性任务. 工作队列主要是为了避免进行一些必须同步等待的资源密集 ...
- RabbitMQ入门教程——工作队列
什么是工作队列 工作队列是为了避免等待一些占用大量资源或时间操作的一种处理方式.我们把任务封装为消息发送到队列中,消费者在后台不停的取出任务并且执行.当运行了多个消费者工作进程时,队列中的任务将会在每 ...
- RabbitMQ入门:工作队列(Work Queue)
在上一篇博客<RabbitMQ入门:Hello RabbitMQ 代码实例>中,我们通过指定的队列发送和接收消息,代码还算是比较简单的. 假设有这一些比较耗时的任务,按照上一次的那种方式, ...
- RabbitMQ入门(2)——工作队列
前面介绍了队列接收和发送消息,这篇将学习如何创建一个工作队列来处理在多个消费者之间分配耗时的任务.工作队列(work queue),又称任务队列(task queue). 工作队列的目的是为了避免立刻 ...
- RabbitMQ 之 WorkQueues工作队列
模型图 为什么会出现 work queues? 前提:使用 simple 队列的时候 (上一篇博客)我们应用程序在是使用消息系统的时候,一般生产者 P 生产消息是毫不费力的(发送消息即可),而消费者接 ...
- (转) RabbitMQ学习之工作队列(java)
http://blog.csdn.net/zhu_tianwei/article/details/40887717 参考:http://blog.csdn.NET/lmj623565791/artic ...
- 译: 2. RabbitMQ Spring AMQP 之 Work Queues
在上一篇博文中,我们写了程序来发送和接受消息从一个队列中. 在这篇博文中我们将创建一个工作队列,用于在多个工作人员之间分配耗时的任务. Work Queues 工作队列(又称:任务队列)背后的主要思想 ...
随机推荐
- 一:SpringCloud
一:前提知识+相关说明 前提知识:springmvc+spring/springboot+mybatis+maven+git...... cloud技术的五大神兽: 面试题: 什么是微服务? 微服务之 ...
- 多线程-synchronized锁
package 多线程.synchronized锁; /*. * * * * */ public class Sale implements Runnable { ; @Override public ...
- redis集群的远程管理与监控
一.redis集群的重要性 目前大部分的互联网平台,都会用到Redis内存数据库,以提高响应速度,提升用户使用体验. 为了实现Redis的高可用,通常都会布署Redis集群,使用Redis-Senti ...
- Spring部分面试知识
对Spring的理解 spring是一个轻量级的开源框架,贯穿持久层.业务逻辑层.控制层.让每一个功能模块都可以独立的分开,降低耦合度,提高代码复用度.spring通过控制反转降低耦合性,一个对象的依 ...
- 关于html 中form表单的内标签和使用
表单标记 1.普通文本框: <input type=”text” name=”名称” value=”值”;不写value默认为空/> 2.密码框:<input type=”passw ...
- vue项目性能优化(路由懒加载、gzip加速、cdn加速)
前端工程性能优化一说意义深远悠长,本章主要介绍除了一些基础优化外如何实行路由懒加载.Gzip加速.CDN加速,让网页飞的快一些. 基础优化 老生常谈的一些: 不要在模板中写复杂的表达式 慎用watch ...
- Ueditor更改编辑框样式
1.在ueditor.all.min.js文件中查找“ueditor.css”,找到位置后更改css文件,或在原文件中更改
- android头像上传(获取头像加剪切)
因为项目中需要用到头像上传的功能,所以就下个Ddmo先来实现下. demo我是类似仿微信的,在一个GridView中展示所有的图片,其中第一个item可以去照相:获取到图片后再进行剪切. 图片的剪切是 ...
- Integer 和 int 值比较
int 是基本数据类型,会进池,可以使用 == 判断两个值相等 Integer是对象,比较对象不能使用 == , 可以使用Integer.intValue()将取出对象值比较
- spring boot(4)-html和templates
静态页面 spring boot项目只有src目录,没有webapp目录,会将静态访问(html/图片等)映射到其自动配置的静态目录,如下 /static /public /resources ...