二.多个消费者同时消费一个列队
来源:互联网 发布:java文件比较 编辑:程序博客网 时间:2024/05/01 01:15
提供者的pom.xml和消费者的pom.xml和第一章一样
一.Producer提供者
发送消息的类:MessageSender.java
package com.rabbitmq.producer;import java.io.IOException;import java.util.concurrent.TimeoutException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;public class MessageSender { private Logger logger = LoggerFactory.getLogger(MessageSender.class); //声明一个列队名字 private final static String QUEUE_NAME = "hello"; /** * 多个消费者同时消费一个列队测试 * 发送者不停的往MQ中发送消息 * @param message * @return */ public boolean sendMessageMany(String message){ //new一个rabbitmq的连接工厂 ConnectionFactory factory = new ConnectionFactory(); //设置需要连接的RabbitMQ的机器的地址,这里指向本机 factory.setHost("localhost"); //连接器 Connection connection = null; //通道 Channel channel = null; try { //尝试获取一个连接 connection = factory.newConnection(); //尝试创建一个通道 channel = connection.createChannel(); /*声明一个列队: * 1.queue队列的名字,是否持久化 为true则在rabbitMQ重启后生存, * 2.是否是排他性队列(别人看不到),只对当前连接有效,当前连接断开后,队列删除(设置了持久化也删除) * 3.自动删除,在最后一个连接断开后删除队列 * 4.其他参数 * */ channel.queueDeclare(QUEUE_NAME,false,false,false,null); /*发布消息,注意这里调用了getBytes(),发送的其实是byte数组,接收方收到消息后,需要重新组装成String * 1.交换模式 * 2.控制消息发送到哪个队列 * 3.其他参数 * 4.body 消息,byte数组 * */ //循环往列队发布消息 int i = 0; String oldMessage = message; while(true){ message+=i++; channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); logger.info("已发送:"+message); try { Thread.sleep(500);//500毫秒发送一次 } catch (InterruptedException e) { logger.info("线程被打断:"+message); } message=oldMessage;//还原消息 //此代码没用,只是为了死循环出现防止编译出错 if(!"q".equals("q")){ break; } } //关闭通道和链接(先关闭通道在关闭连接) channel.close(); connection.close(); } catch (IOException e) { logger.error("IO异常:"+e); return false; } catch (TimeoutException e){ logger.error("超时异常:"+e); return false; } return true; }}
2.测试发送消息的Main:ManySenderMain.java
package com.rabbitmq.main;import com.rabbitmq.producer.MessageSender;public class ManySenderMain { public static void main(String[] args) { MessageSender messageSender = new MessageSender(); messageSender.sendMessageMany("hellow tiglle"); }}
二.Consumer消费者:
1.接收消息的消费者类:
package com.rabbitmq.consumer;import java.io.IOException;import java.util.concurrent.TimeoutException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.rabbitmq.client.AMQP;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;import com.rabbitmq.client.Consumer;import com.rabbitmq.client.DefaultConsumer;import com.rabbitmq.client.Envelope;public class MessageRecive { private Logger logger = LoggerFactory.getLogger(MessageRecive.class); //多个消费者消费消息:增加了是哪个消费者的标记 public boolean manyConsume(String queueName,final String flag){ //连接rabbitmq ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); Connection connection = null; Channel channel =null; //声明消费的queue try { connection = factory.newConnection(); channel = connection.createChannel(); channel.queueDeclare(queueName,false,false,false,null); //这里重写了DefaultConsumer的handleDelivery方法,因为发送的时候对消息进行了getByte(),在这里要重新组装成String Consumer consumer = new DefaultConsumer(channel){ //重写父类方法 @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)throws IOException { String message = new String(body, "UTF-8"); logger.info("["+flag+"]接收到:" + message); } }; //上面是声明消费者,这里用 声明的消费者 消费 列队的消息 channel.basicConsume(queueName, true,consumer); //这里不能关闭连接,调用了消费方法后,消费者会一直连接着rabbitMQ等待消费 } catch (Exception e) { logger.error("出现异常:"+e); return false; } return true; }}
3.测试启动多个消费者开始监听消费消息的Main方法:ManyReviceMain.java
package com.rabbitmq.main;import com.rabbitmq.consumer.MessageRecive;//多个消费之同时消费列队的消息public class ManyReviceMain { //这个队列名字要和生产者中的名字一样,否则找不到队列 private final static String QUEUE_NAME = "hello"; /** * 测试多个客户端消费提供者的消息 * 可以看出消息会平均发送个每个消费者 * RabbitMQ的特性,称作“Round-robin dispatching”,消息会平均的发送给每一个消费者 * @param args */ public static void main(String[] args) { MessageRecive messageRecive1 = new MessageRecive(); messageRecive1.manyConsume(QUEUE_NAME, "consumer1"); MessageRecive messageRecive2 = new MessageRecive(); messageRecive2.manyConsume(QUEUE_NAME, "consumer2"); MessageRecive messageRecive3 = new MessageRecive(); messageRecive3.manyConsume(QUEUE_NAME, "consumer3"); MessageRecive messageRecive4 = new MessageRecive(); messageRecive4.manyConsume(QUEUE_NAME, "consumer4"); }}
可以看到,提供者不停的发送消息,四个消费者是平均规律的分摊了消费者的消息。
RabbitMQ的特性,称作“Round-robin dispatching”,消息会平均的发送给每一个消费者
阅读全文
0 0
- 二.多个消费者同时消费一个列队
- ActiveMQ多个消费者监听一个列队,最后是谁消费了?
- ActiveMQ多个消费者消费不均匀问题
- 编写一个多线程程序,模拟2个生产者生产产品,3个消费者消费产品。2个生产者不停的生产商品3个消费者不停的消费产品。
- 一个生产者多个消费者问题
- 一个按钮同时触发二个验证JS函数
- 一个mysql同时运行多个服务
- 一个Myeclipse同时配置多个Tomcat
- 一个Myeclipse同时配置多个Tomcat
- 一个Myeclipse同时配置多个Tomcat
- 一个Myeclipse同时配置多个Tomcat
- 一个串口同时传输多个数据
- 一个Myeclipse同时配置多个Tomcat
- 一个电脑同时开启一个或者多个Tomcat
- java多线程 一个生产者和多个消费者
- RabbitMQ消息通信,一个生产者和多个消费者
- 一个生产者一个消费者的无锁队列,多个生产者多个消费者的无锁队列
- 生产消费模型-多生产者vs多消费者
- 2017.07.06-0709 没写日记
- 解决问题:Could not find method android() for arguments
- 代码质量,代码规范,可维护性,可拓展性,高性能
- 共享单车上的智能锁,做出来有多难?
- [CLI]sync
- 二.多个消费者同时消费一个列队
- 各种语言之父
- Thinkphp5配置文件及配置类记录
- 2017上海金马五校 购买装备 贪心+二分Check
- zookeeper学习__分布式共享锁简单Demo
- java之回调函数
- Mac book pro wifi 频繁掉线,解决方案
- 1046. 划拳(15)
- JavaScript精华知识之函数部分