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 工作队列(又称:任务队列)背后的主要思想 ...
随机推荐
- Java异步转同步
参考原文: <http://blog.csdn.net/veson__/article/details/53898890>
- jetbrains激活 webstorm激活 webstorm激活码
License Activation的破解方式无效时,请采用以下方法1. 把下载的破解补丁放在你的idea的安装目录下的bin的目录下面(如下图所示),本文示例为C:\Program Files\Je ...
- 插件式WebApi服务及自动生成Api帮助文档
上一篇博客中,讲到了将WebApi Host到控制台和IIS,本篇总结一下如何将WebApi的Service以插件的形式进行动态部署,并设置Hoster的首页显示Api帮助文档,当然,也包括动态部署进 ...
- Date()函数的用法
- AJAX 概念 优势 发展前景 工作原理 底层技术 状态 缺点 框架
1. 概念 Ajax asynchronous JavaScript and XML , 异步js和xml. 这种解释已经过时了, 现在ajax就是, 允许浏览器和服务器通信, 而无需刷新当前页面的技 ...
- Angular入门教程二
4 功能介绍 4.1数据绑定 AngularJS的双向数据绑定,意味着你可以在Mode(JS)中改变数据,而这些变动立刻就会自动出现在View上,反之亦然.即:一方面可以做到model变化驱动了DOM ...
- 搭建hustoj
环境:centos6.5 + LAMP环境 LAMP环境的搭建可以参考下面这篇文章 http://www.cnblogs.com/yoke/p/7257184.html 搭建完LAMP环境之后可以按照 ...
- python学习笔记之——正则表达式
1.re模块 Python通过re模块提供对正则表达式的支持,re 模块使 Python 语言拥有全部的正则表达式功能.使用re的一般步骤是先将正则表达式的字符串形式编译为Pattern实例,然后使用 ...
- 通过Application存取公共数据比如登录信息等..
Android系统在运行每一个程序应用的时候,都会创建一个Application对象,用于存储与整个应用相关的公共变量.一个Android应用只会生成一个Application对象,在不同的Activ ...
- RHEL生命周期管理 -- Should I stay, or should I go?
1. RHEL的支持策略是怎么样的? 标准支持(一般7年)+ 延长支持(3年) 2. 升级RHEL的好处有哪些? More advantageous to upgrade completely to ...