RabbitMQ如何高效的消费消息

在上篇介绍了如何简单的发送一个消息队列之后,我们本篇来看下RabbitMQ的另外一种模式,工作队列

什么是工作队列

我们上篇文章说的是,一个生产者生产了消息被一个消费者消费了,如下图

上面这种简单的消息队列确实可以处理我们的任务,但是当我们队列中的任务过多,处理每条任务有需要很长的耗时,那么使用一个消费者处理消息显然不不够的,所以我们可以增加消费者,来共享消息队列中的消息,进行任务处理。

也就是如下图

虽然上图我只花了一个生产者A,那么同理,能有多个消费者,那也能多个生产者。

代码

发送消息

1public class Send { 2 3 public static final String QUEUE_NAME = "test_word_queue"; 4 5 public static void main(String[] args) throws IOException, TimeoutException, InterruptedException { 6 7 // 获取连接 8 Connection connection = MQConnectUtil.getConnection(); 9 10 // 创建通道 11 Channel channel = connection.createChannel(); 12 13 // 声明队列 14 channel.queueDeclare(QUEUE_NAME, false, false, false, null); 15 16 // 模拟发送20条消息 17 for (int i = 0; i < 20; i++) { 18 19 String msg = "消息:" + i; 20 21 channel.basicPublish("", QUEUE_NAME, null, msg.getBytes()); 22 23 Thread.sleep(i * 20); 24 25 System.out.println(msg); 26 } 27 28 channel.close(); 29 connection.close(); 30 } 31}

消费者A

1public class Consumer1 { 2 3 public static final String QUEUE_NAME = "test_word_queue"; 4 5 public static void main(String[] args) throws Exception { 6 7 // 获取连接 8 Connection connection = MQConnectUtil.getConnection(); 9 10 // 创建频道 11 Channel channel = connection.createChannel(); 12 13 // 队列声明 14 channel.queueDeclare(QUEUE_NAME, false, false, false, null); 15 16 // 定义消费者 17 DefaultConsumer consumer = new DefaultConsumer(channel) { 18 @SneakyThrows 19 @Override 20 public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) { 21 String msg = new String(body, StandardCharsets.UTF_8); 22 23 System.out.println("消费者[A]-内容:" + msg); 24 25 Thread.sleep(2 * 1000); 26 } 27 }; 28 29 // 监听队列 30 channel.basicConsume(QUEUE_NAME, true, consumer); 31 } 32}

消费者B

1public class Consumer2 { 2 3 public static final String QUEUE_NAME = "test_word_queue"; 4 5 public static void main(String[] args) throws Exception { 6 7 // 获取连接 8 Connection connection = MQConnectUtil.getConnection(); 9 10 // 创建频道 11 Channel channel = connection.createChannel(); 12 13 // 队列声明 14 channel.queueDeclare(QUEUE_NAME, false, false, false, null); 15 16 // 定义消费者 17 DefaultConsumer consumer = new DefaultConsumer(channel) { 18 @SneakyThrows 19 @Override 20 public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) { 21 String msg = new String(body, StandardCharsets.UTF_8); 22 23 System.out.println("消费者[B]-内容:" + msg); 24 25 Thread.sleep(1000); 26 } 27 }; 28 29 // 监听队列 30 channel.basicConsume(QUEUE_NAME, true, consumer); 31 } 32}

我们来看下消费者A和消费者B的消费情况

  • 消费者B

  • 消费者A

有没有发现什么问题,我总过模拟发送了20条消息,细心的同学可以发现,消费者A和消费者B消费了同样多的消息,都消费了10天,但是我在消费者A和消费者B中,什么sleep不通的时长,按道理说消费者B要比消费者A处理消息的速度块,处理的消息更多,那么为什么会产生这样的原因?

RabbitMQ工作队列的默认配置

默认情况下,RabbitMQ会将每个消息依次发送给下一个消费者,每个消费者收到的消息数量其实是一样的,我们把这种分发消息的方式称为轮训分发模式

本篇我们就简单介绍这么多内容,有心学习的童鞋一定要敲敲代码,看不一定能看会,只有自己敲一遍,才能有所理解。

<p style="text-align:center;font-weight:bold;color:#0e88eb;font-size:20px">日拱一卒,功不唐捐</p>

更多内容请关注:

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )