rabbitmq 启动多个消费者_RabbitMQ六种队列模式-工作队列模式

RabbitMQ六种队列模式-工作队列模式

上一篇介绍了简单队列,但是简单队列有个缺点,简单队列是一一对应的关系,即点对点,一个生产者对应一个消费者,按照这个逻辑,如果我们有一些比较耗时的任务,也就意味着需要大量的时间才能处理完毕,显然简单队列模式并不能满足我们的工作需求,我们今天再来看看工作队列。

8bcd77c2ef7d0c39bc7fcf2ba584decd.png

什么是工作队列

工作队列:用来将耗时的任务分发给多个消费者(工作者)。

主要解决问题:处理资源密集型任务,并且还要等他完成。有了工作队列,我们就可以将具体的工作放到后面去做,将工作封装为一个消息,发送到队列中,一个工作进程就可以取出消息并完成工作。如果启动了多个工作进程,那么工作就可以在多个进程间共享。

工作队列也称为公平性队列模式,怎么个说法呢?

循环分发,假如我们拥有两个消费者,默认情况下,RabbitMQ 将按顺序将每条消息发送给下一个消费者,平均而言,每个消费者将获得相同数量的消息,这种分发消息的方式称为轮询。

代码部分

2.1 生产者

创建50个消息

package com.shuofeng.producer; import java.io.IOException;import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.shuofeng.common.MQConnectionUtils; public class Producer2 {//队列名称private static final String QUEUE_NAME = "test001_queue";public static void main(String[] args) throws IOException, TimeoutException {//1.获取连接Connection newConnection = MQConnectionUtils.newConnection();//2.创建通道Channel channel = newConnection.createChannel();//3.创建队列声明channel.queueDeclare(QUEUE_NAME, false, false, false, null);//保证一次只分发一次 限制发送给同一个消费者 不得超过一条消息channel.basicQos(1);for(int i = 0;i < 50;i++) {String msg = "生产者消息_"+i;        System.out.println("生产者发送消息:" + msg);        //4.发送消息        channel.basicPublish("",QUEUE_NAME, null, msg.getBytes());}//5.关闭队列channel.close();newConnection.close();}}

2.2 消费者

消费者1

package com.shuofeng.customer; import java.io.IOException;import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.DefaultConsumer;import com.rabbitmq.client.Envelope;import com.rabbitmq.client.AMQP.BasicProperties;import com.shuofeng.common.MQConnectionUtils; public class Customer2_1 {//队列名称private static final String QUEUE_NAME = "test001_queue";public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接Connection newConnection = MQConnectionUtils.newConnection();//2.获取通道final Channel channel = newConnection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);//保证一次只分发一次 限制发送给同一个消费者 不得超过一条消息channel.basicQos(1);DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)throws IOException {String msgString = new String(body, "UTF-8");                System.out.println("消费者获取消息:" + msgString);                try {Thread.sleep(1000);} catch (Exception e) {// TODO: handle exception} finally {//手动回执消息channel.basicAck(envelope.getDeliveryTag(), false);}}};//3.监听队列channel.basicConsume(QUEUE_NAME, false, defaultConsumer);}}

消费者2

package com.shuofeng.customer; import java.io.IOException;import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.DefaultConsumer;import com.rabbitmq.client.Envelope;import com.rabbitmq.client.AMQP.BasicProperties;import com.shuofeng.common.MQConnectionUtils; public class Customer2_2 {//队列名称private static final String QUEUE_NAME = "test001_queue";public static void main(String[] args) throws IOException, TimeoutException {//1.创建连接Connection newConnection = MQConnectionUtils.newConnection();//2.获取通道final Channel channel = newConnection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);//保证一次只分发一次 限制发送给同一个消费者 不得超过一条消息channel.basicQos(1);DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)throws IOException {String msgString = new String(body, "UTF-8");                System.out.println("消费者获取消息:" + msgString);                try {Thread.sleep(1000);} catch (Exception e) {// TODO: handle exception} finally {//手动回执消息channel.basicAck(envelope.getDeliveryTag(), false);}}};//3.监听队列channel.basicConsume(QUEUE_NAME, false, defaultConsumer);}}

3、循环分发

3.1 启动生产者

f8f317b6ae70a8650d44c87bb78b0d9d.png

3.2 启动消费者

消费者1

9d1ad589d9df6105df425b0e4d2be0a6.png

消费者2

95664460a9f63bc42753e6e3720d5b6a.png

在生产者中我们发送了50条消息进入队列,而上方消费者启动图里很明显的看到轮询的效果,就是每个消费者会分到相同的队列任务。而且收到的数据不会重复。

4、工作队列总结

1、循环分发:消费者端在信道上打开消息应答机制,并确保能返回接收消息的确认信息,这样可以保证消费者发生故障也不会丢失消息。

2、消息持久化:服务器端和客户端都要指定队列的持久化和消息的持久化,这样可以保证RabbitMQ重启,队列和消息也不会丢失。

3、公平分发:指定消费者接收的消息个数,避免出现消息均匀推送出现的资源不合理利用的问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值