上一篇博客的作为rabbitMQ的入门程序,也是简单队列模式,一个生产者,一个消费者,今天这篇博客介绍work模式,一个生产者,多个消费者,下面的例子模拟两个消费者的情况。

图示:
        

一个生产者、两个消费者;一个消息只能被一个消费者获取。

在work模式中可以分为两种模式,一种是两个消费者平均消费队列中的消息,即使他们的消费能力是不一样的,这种似乎不太符合实际的情况。另一种是能者多劳模式,处理消息能力强的消费者会获取更多的 消息,这种模式更符合实际需求。

生产者:向队列发送50条消息,下面代码中,生产者每生产一条消息后都会休眠一段时间,并且越往后休眠的时间越长。

public class Send {
private final static String QUEUE_NAME = "test_queue_work";
public static void main(String[] argv) throws Exception {
// 获取到连接以及mq通道
Connection connection = ConnectionUtil.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(" [x] Sent '" + message + "'");
Thread.sleep(i * 10);
}
channel.close();
connection.close();
}
}

消费者1:休眠时间为10ms

public class Recv {
private final static String QUEUE_NAME = "test_queue_work";
public static void main(String[] argv) throws Exception {
// 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
// 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 同一时刻服务器只会发一条消息给消费者
//channel.basicQos(1);
// 定义队列的消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
// 监听队列,手动返回完成
channel.basicConsume(QUEUE_NAME, false, consumer);
// 获取消息
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
//休眠
Thread.sleep(10);
// 返回确认状态
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}

消费者2:休眠时间为1000ms

public class Recv2 {
private final static String QUEUE_NAME = "test_queue_work";
public static void main(String[] argv) throws Exception {
// 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
// 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 同一时刻服务器只会发一条消息给消费者
//channel.basicQos(1);
// 定义队列的消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
// 监听队列,手动返回完成状态
channel.basicConsume(QUEUE_NAME, false, consumer);
// 获取消息
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的休眠时间更长,消费者1的处理能力应该比消费者2更强,但是最后运行的结果会发现,两个消费者获得消息的数量十一样的,一个全部为奇数,一个全部为偶数。

我们把每个消费者中的代码:channel.basicQos(1);这句代码解开注释会发现消费者2获取到8条数据,而消费者1获取到42条消息。这样
的结果才符合work模式的能者多劳模式。这句代码表示服务器同一时刻只会发送一条消息给消费者,但并不指定是哪个消费者,处理能力高的人会接收到更多的
消息。

小结:

简单队列和work 模式的不同:
  简单队列只要消息从队列中获取,无论消费者获取到消息后是否成功消费,比如遇到状况:断电,都认为是消息已经成功消费;

work模式消费者从队列中获取消息后,服务器会将该消息标记为不可用状态,等待消费者反馈,如果消费这一直没有反馈,则该消息一直处于不可用状态。

具体使用哪种模式具体问题具体分析。

channel.basicConsume(QUEUE_NAME, false, consumer);false表示监听队列,手动返回完成状态,true表示自动返回。

【RabbitMQ】3、工作队列模式(work模式)的更多相关文章

  1. RabbitMQ六种队列模式-路由模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式 [本文]RabbitMQ六种队列模式-主 ...

  2. RabbitMQ六种队列模式-主题模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主题模式 [ ...

  3. RabbitMQ从零到集群高可用(.NetCore5.0) - RabbitMQ简介和六种工作模式详解

    一.RabbitMQ简介 是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,RabbitMQ是使用Erlang(高并发语言)语言来编写的,并且RabbitMQ是基于AMQ ...

  4. RabbitMQ入门_03_推拉模式

    我们知道,消费者有两种方式从消息中间件获取消息: 推模式:消息中间件主动将消息推送给消费者 拉模式:消费者主动从消息中间件拉取消息 推模式将消息提前推送给消费者,消费者必须设置一个缓冲区缓存这些消息. ...

  5. RabbitMQ 最常用的三大模式

    目录 Direct 模式 Topic 模式 Fanout 模式 Direct 模式 所有发送到 Direct Exchange 的消息被转发到 RouteKey 中指定的 Queue. Direct ...

  6. (九)RabbitMQ消息队列-通过Headers模式分发消息

    原文:(九)RabbitMQ消息队列-通过Headers模式分发消息 Headers类型的exchange使用的比较少,以至于官方文档貌似都没提到,它是忽略routingKey的一种路由方式.是使用H ...

  7. (七)RabbitMQ消息队列-通过fanout模式将消息推送到多个Queue中

    原文:(七)RabbitMQ消息队列-通过fanout模式将消息推送到多个Queue中 前面第六章我们使用的是direct直连模式来进行消息投递和分发.本章将介绍如何使用fanout模式将消息推送到多 ...

  8. rabbitmq 持久化 事务 发送确认模式

    部分内容来自:http://blog.csdn.net/hzw19920329/article/details/54315940 http://blog.csdn.net/hzw19920329/ar ...

  9. RabbitMq学习2-php命令行模式测试rabbitmq

    一.RabbitMQ结构 1.几个概念说明:       Broker:简单来说就是消息队列服务器实体. Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列. Queue:消息队列载体 ...

  10. RabbitMQ 3.9.7 镜像模式集群的搭建

    1. 概述 老话说的好:做人脚踏实地,一步一个脚印,便定能战胜一切困难,最终取得成功!!! 言归正传,之前我们聊了 RabbitMQ 单点服务的安装,今天我们来聊聊 RabbitMQ 3.9.7 镜像 ...

随机推荐

  1. Ruby(2): 基本语法上

    表达式和变量: 这两点和其他主流的编程语言基本没有差别,这里直接跳过. 需要注意的是 ruby中 x=x+1 可以写成 x+=1 但是不支持 x++ , x-- 等一元运算符  比较运算符和表达式: ...

  2. IOS Runtime属性关联实现表格编辑文本

    要实现在表格里编辑文本, 表格让我想到了CollectionView,文本让我想起TextView, 做之前想了好久怎么样来获得编辑的是哪个TextView,要获取对应的IndexPath啊,想着之前 ...

  3. 编译android源码遇到错误及其解决方法

    升级ubuntu的14.04后,android的源码又编译错误了,一下是错误说明赫解决方法: 1.make: *** [out/host/linux-x86/obj/EXECUTABLES/aidl_ ...

  4. 图标插件FusionChartsFree

    二.介绍 Ø FusionCharts 是InfoSoft Global 公司的一个产品,InfoSoft Global 公司是专业的Flash 图形方案提供商,他们还有几款其他的,基于Flash 技 ...

  5. jquery 获取 tagName(JQuery如何得到tagName?)

    在javascript中要取得tagName十分简单,但在jQuery中官方文档却没有记载,在一通百度和谷歌之后,尝试了不少所谓秘技,都不能正确得到,经过自己的验证,终于找到了方法,于是记录下来以备忘 ...

  6. jquery datatables 学习笔记

    最近项目中用到了BootStrap做后台,在选择表格插件的时候发现了jquery datatables. 功能是很强大,但是网上的例子比较少.在经过一段时间的努力可算是搞出来了. 官网地址:http: ...

  7. c# 根据父节点id,找到所有的子节点数据

    转自:https://blog.csdn.net/q107770540/article/details/7708418 查的是表 Model_info中父节点为p_id时找到所有的子节点的集合 //通 ...

  8. 【SSH网上商城项目实战04】EasyUI菜单的实现

    转自:https://blog.csdn.net/eson_15/article/details/51297705 上一节我们使用EasyUI搭建了后台页面的框架,这一节我们主要使用EasyUI技术简 ...

  9. hdu 1397 (素数判定)

    一开始提交了这个,果断TLE #include <cstdio> #include <iostream> #include <string> #include &l ...

  10. HTML5 Canvas中绘制椭圆的几种方法

    1.canvas自带的绘制椭圆的方法 ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)是后来 ...