由于在实际应用中,简单队列模型无法解决很多实际问题,而且生产者和消费者是一对一的关系。模型较为单一。故引入Work模式。

结构图

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

测试实现: 
1、生产者

 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();
}

生产者循环创建消息 
2、消费者一

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);
}
}

3、消费者二 
注意:channel.basicQos(1); 被注释掉了

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);
}
}

测试结果:

1、 消费者1和消费者2获取到的消息内容是不同的,同一个消息只能被一个消费者获取。 
2、 消费者1和消费者2获取到的消息的数量是相同的,一个是奇数一个是偶数。

其实,这样是不合理的,应该是消费者1要比消费者2获取到的消息多才对。

消息的确认模式

消费者从队列中获取消息,服务端如何知道消息已经被消费呢?

模式1:自动确认

只要消息从队列中获取,无论消费者获取到消息后是否成功消息,都认为是消息已经成功消费。

模式2:手动确认

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

应用场景

集群中同时监听一个服务队列

RabbitMQ五种消息队列学习(三)–Work模式的更多相关文章

  1. Rabbit五种消息队列学习(一) – 总述

    RabbitMQ支持五种消息传递类型,分别如下图所示: 上图中显示6中消息队列分别为: 1.简单队列 一个生产者将消息放到队列中,一个消费者监听队列 2.工作队列(Work queues) 一个生产者 ...

  2. Rabbit五种消息队列学习(二) – 简单队列

    队列结构图 P:消息的生产者 C:消息的消费者 红色:队列 生产者将消息发送到队列,消费者从队列中获取消息. 测试 1.连接MQ public static Connection getConnect ...

  3. 学习ActiveMQ(五):activemq的五种消息类型和三种监听器类型

    一.前面我们一直发送的是字符串类型,其实activemq一共支持五种消息类型: 1.String消息类型:发送者:消费者: 1.String消息类型:发送者:消费者: 1.String消息类型:发送者 ...

  4. rabbitmq五种消息模型整理

    目录 0. 配置项目 1. 基本消息模型 1.1 生产者发送消息 1.2 消费者获取消息(自动ACK) 1.3 消息确认机制(ACK) 1.4 消费者获取消息(手动ACK) 1.5 自动ACK存在的问 ...

  5. RabbitMQ,RocketMQ,Kafka 几种消息队列的对比

    常用的几款消息队列的对比 前言 RabbitMQ 优点 缺点 RocketMQ 优点 缺点 Kafka 优点 缺点 如何选择合适的消息队列 参考 常用的几款消息队列的对比 前言 消息队列的作用: 1. ...

  6. RabbitMQ之五种消息模型

    首先什么是MQ MQ全称是Message Queue,即消息对列!消息队列是典型的:生产者.消费者模型.生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息.因为消息的生产和消费都是异步的,而 ...

  7. (八)RabbitMQ消息队列-通过Topic主题模式分发消息

    原文:(八)RabbitMQ消息队列-通过Topic主题模式分发消息 前两章我们讲了RabbitMQ的direct模式和fanout模式,本章介绍topic主题模式的应用.如果对direct模式下通过 ...

  8. RabbitMQ AMQP (高级消息队列协议)

    目录 RabbitMQ AMQP (高级消息队列协议) Message Queue 简介 概念 基本组成 场景及作用 AMQP简介 模型架构 基础组件 AMQP-RabbitMQ 简介 模型 特性 参 ...

  9. 第二百九十一节,RabbitMQ多设备消息队列-安装与简介

    RabbitMQ多设备消息队列-安装与简介 RabbitMQ简介 解释RabbitMQ,就不得不提到AMQP(Advanced Message Queuing Protocol)协议. AMQP协议是 ...

随机推荐

  1. 给力的移动 FZU - 2287

    你的弟弟给你安排了一个任务,他给了你1到N个数字的乱序排列,现在你想给你的弟弟秀一波操作,操作最少的次数把序列变成1到N的顺序排列,每次操作你可以选择序列中的一个数字并把它移动到序列的头部或尾部. I ...

  2. HDU 2888 Check Corners (模板题)【二维RMQ】

    <题目链接> <转载于 >>> > 题目大意: 给出一个N*M的矩阵,并且给出该矩阵上每个点对应的值,再进行Q次询问,每次询问给出代询问子矩阵的左上顶点和右下 ...

  3. 分布式服务框架XXL-RPC

    <分布式服务框架XXL-RPC>      一.简介 1.1 概述 XXL-RPC 是一个分布式服务框架,提供稳定高性能的RPC远程服务调用功能.拥有"高性能.分布式.注册中心. ...

  4. 开源医学图像处理平台NiftyNet介绍

    18年下半年10月份左右,老师分配有关NiftyNet平台的相关学习的任务,时隔5个月,决定整理一下以前的笔记,写成相应的博客! 目录 1.NiftyNet平台简介 2.NiftyNet平台架构设计 ...

  5. 算法进阶面试题07——求子数组的最大异或和(前缀树)、换钱的方法数(递归改dp最全套路解说)、纸牌博弈、机器人行走问题

    主要讲第五课的内容前缀树应用和第六课内容暴力递归改动态规划的最全步骤 第一题 给定一个数组,求子数组的最大异或和. 一个数组的异或和为,数组中所有的数异或起来的结果. 简单的前缀树应用 暴力方法: 先 ...

  6. opencv3 学习笔记(二)

    1.OpenCv 颜色追踪 import cv2import numpy as npcap=cv2.VideoCapture(0)cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1 ...

  7. Redis自学笔记:3.5入门-集合类型

    3.5集合类型 3.5.1介绍 在集合中的每个元素都是不同的,且没有顺序 表3-4集合类型和列表类型的对比 - 集合类型 列表类型 存储内容 至多232-1个字符串 至多232-1个字符串 有序性 否 ...

  8. VMware5.5-添加数据中心,集群及主机

    首先介绍下硬盘的三种设置格式,这个要搞清楚 虚机硬盘的三种格式 厚置备延迟置零 厚置备,分配10g空间,虚拟机没开机时就分配了: 延迟置零,没开机之前只分配空间,里面的数据不抹零,当开机写入数据时再抹 ...

  9. Markdown使用简介 及 学习资源整理

    Markdown资源整理 官网 http://daringfireball.net/projects/markdown/ http://jgm.github.io/stmd/spec.html htt ...

  10. android Resources 类的使用

    使用 R.<resource_type>.<resource_name> 获取的是资源的一个 id (int 类型), 但有时候我们需要获取资源本身,这时候我们可以通过 Res ...