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 工作队列(又称:任务队列)背后的主要思想 ...
随机推荐
- freemarker学习笔记
在模板中定义的变量有三种类型: 引用 1:plain变量:可以在模板的任何地方访问,包括使用include指令插入的模板,使用assign指令创建和替换. 2:局部变量:在宏定义体中有效,使用loca ...
- JS 监听键盘按键
1. 实现Ctrl+ Enter 组合键触发事件 document.onkeydown=function(event){ var keyNum = window.event ? event.keyCo ...
- Mybatis之简单注解
Mybatis使用注解实现主键自增长: oracle: @SelectKey(statement="select my_seq.nextval from dual",resultT ...
- 中南月赛F ZZY and his little friends
Problem F: ZZY and his little friends Time Limit: 5 Sec Memory Limit: 256 MBSubmit: 137 Solved: 70 ...
- fuzhou 1683 纪念SlingShot ***
Problem 1683 纪念SlingShot Accept: 361 Submit: 1287Time Limit: 1000 mSec Memory Limit : 32768 KB ...
- 让你跟上nodejs的资源
For a long time, JavaScript developers hoped for a server-side solution that would allow them to ful ...
- ionic--配置路由
1.ng-route index中引用文件: <script src="ionic.bundle.js"></script> <script src= ...
- JS cookie 设置 查看 删除
JScookie 常用的3个预设函数(库) <!DOCTYPE HTML> <html> <head> <meta charset="utf-8&q ...
- MD5计算器
private void radioBtnFlie_CheckedChanged(object sender, EventArgs e) { RadioButton rb = sender as Ra ...
- 如何验证一份HTML文档的格式是否正确
在浏览器中打开 Markup Validation Service . 点击或者激活 Validate by Direct Input 栏. 将整个示范文档的代码(不仅仅是body部分)复制粘贴到在M ...