(转) RabbitMQ学习之工作队列(java)
http://blog.csdn.net/zhu_tianwei/article/details/40887717
参考:http://blog.csdn.NET/lmj623565791/article/details/37620057
1.生产任务Task.Java
- package cn.slimsmart.rabbitmq.demo.workqueue;
- import com.rabbitmq.client.AMQP;
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.ConnectionFactory;
- import com.rabbitmq.client.MessageProperties;
- public class Task {
- //队列名称
- private final static String QUEUE_NAME = "workqueue-durable";
- public static void main(String[] args) throws Exception {
- //创建连接和频道
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("192.168.101.174");
- //指定用户 密码
- factory.setUsername("admin");
- factory.setPassword("admin");
- //指定端口
- factory.setPort(AMQP.PROTOCOL.PORT);
- Connection connection = factory.newConnection();
- Channel channel = connection.createChannel();
- boolean durable = true; //设置消息持久化 RabbitMQ不允许使用不同的参数重新定义一个队列,所以已经存在的队列,我们无法修改其属性。
- //声明队列
- channel.queueDeclare(QUEUE_NAME, durable, false, false, null);
- //发送10条消息,依次在消息后面附加1-10个点
- for (int i = 5; i > 0; i--)
- {
- String dots = "";
- for (int j = 0; j <= i; j++)
- {
- dots += ".";
- }
- String message = "helloworld" + dots+dots.length();
- //MessageProperties.PERSISTENT_TEXT_PLAIN 标识我们的信息为持久化的
- channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
- System.out.println("Sent Message:'" + message + "'");
- }
- //关闭频道和资源
- channel.close();
- connection.close();
- }
- }
2.消费工作队列
- package cn.slimsmart.rabbitmq.demo.workqueue;
- import com.rabbitmq.client.AMQP;
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.ConnectionFactory;
- import com.rabbitmq.client.QueueingConsumer;
- public class Work {
- //队列名称
- private final static String QUEUE_NAME = "workqueue-durable";
- public static void main(String[] args) throws Exception {
- //区分不同工作进程的输出
- int hashCode = Work.class.hashCode();
- //创建连接和频道
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("192.168.101.174");
- //指定用户 密码
- factory.setUsername("admin");
- factory.setPassword("admin");
- //指定端口
- factory.setPort(AMQP.PROTOCOL.PORT);
- Connection connection = factory.newConnection();
- Channel channel = connection.createChannel();
- boolean durable = true; //设置消息持久化 RabbitMQ不允许使用不同的参数重新定义一个队列,所以已经存在的队列,我们无法修改其属性。
- //声明队列
- channel.queueDeclare(QUEUE_NAME, durable, false, false, null);
- QueueingConsumer consumer = new QueueingConsumer(channel);
- /**
- * ack= true: Round-robin 转发 消费者被杀死,消息会丢失
- * ack=false:消息应答 ,为了保证消息永远不会丢失,RabbitMQ支持消息应答(message acknowledgments)。
- * 消费者发送应答给RabbitMQ,告诉它信息已经被接收和处理,然后RabbitMQ可以自由的进行信息删除。
- * 如果消费者被杀死而没有发送应答,RabbitMQ会认为该信息没有被完全的处理,然后将会重新转发给别的消费者。
- * 通过这种方式,你可以确认信息不会被丢失,即使消者偶尔被杀死。
- * 消费者需要耗费特别特别长的时间是允许的。
- *
- */
- boolean ack = false ; //打开应答机制
- // 指定消费队列
- channel.basicConsume(QUEUE_NAME, ack, consumer);
- //公平转发 设置最大服务转发消息数量 只有在消费者空闲的时候会发送下一条信息。
- int prefetchCount = 1;
- channel.basicQos(prefetchCount);
- while (true)
- {
- QueueingConsumer.Delivery delivery = consumer.nextDelivery();
- String message = new String(delivery.getBody());
- System.out.println(hashCode + " Received Message:'" + message + "'");
- doWork(message);
- System.out.println(hashCode + " Received Done");
- //发送应答
- channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
- }
- }
- /**
- * 每个点耗时1s
- * @param task
- * @throws InterruptedException
- */
- private static void doWork(String task) throws InterruptedException
- {
- for (char ch : task.toCharArray())
- {
- if (ch == '.')
- Thread.sleep(1000);
- }
- }
- }
多启动几个消费者工作进程,使用生产者发送消息,可以观察消费情况。
要了解RabbitMQ的路由机制,exchange是一个关键。exchange可以叫做交换机,也似乎可以叫做路由器,反正它是用来选择路由的。RabbitMQ的核心思想就是消息的发布者不是直接把消息发送到目标队列中的,事实上,通常它并不知道消息要发到哪个队列中,它只知道把消息队列发送到exchange中。exchange一边接收发送者发过来的消息,而另一边则把消息发送到目标队列中去。exchange一定知道哪些队列需要接收这个消息,是加到一个队列里还是加到好几个队列里,还是直接扔掉。
channel.BasicPublish("", "TaskQueue", properties, bytes);
direct exchange 发送消息是要看routingKey的。举个例子,定义了一个direct exchange 名字是X1,然后一个queue名字为Q1 用routingKey=K1 绑定到exchange X1上,当一个routeKey为 K2 的消息到达X1上,那么只有K1=K2的时候,这个消息才能到达Q1上。
fanout类型的exchange就比较好理解。就是简单的广播,而且是忽略routingKey的。所以只要是有queue绑定到fanout exchange上,通过这个exchange发送的消息都会被发送到那些绑定的queue中,不管你有没有输入routingKey。
Topic类型的exchange给与我们更大的灵活性。通过定义routingKey可以有选择的订阅某些消息,此时routingKey就会是一个表达式。exchange会通过匹配绑定的routingKey来决定是否要把消息放入对应的队列中。有两种表达式符号可以让我们选择:#和*。
*(星号):代表任意的一个词。 例:*.a会匹配a.a,b.a,c.a等
#(井号):代码任意的0个或多个词。 例:#.a会匹配a.a,aa.a,aaa.a等
topic exchange 有时候的行为会像其他类型的exchange,比如说:
当routingKey只是有#号的时候,它的行为和fanout的行为是一样的。
当routingKey什么的没有,空字符串的时候,它的行为是和direct是一样的。
要注意的是,符号代表的是词不是字符。RabbitMQ中在表达式中词的定义是以.(点号)分隔的。
Headers类型的exchange使用的比较少。以后再说。
下面主要用代码,实现一下direct、fanout、topic的效果。
(转) RabbitMQ学习之工作队列(java)的更多相关文章
- RabbitMQ学习总结 第三篇:工作队列Work Queue
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- (转) RabbitMQ学习之远程过程调用(RPC)(java)
http://blog.csdn.net/zhu_tianwei/article/details/40887885 在一般使用RabbitMQ做RPC很容易.客户端发送一个请求消息然后服务器回复一个响 ...
- (转)RabbitMQ学习之Headers交换类型(java)
http://blog.csdn.net/zhu_tianwei/article/details/40923131 Headers类型的exchange使用的比较少,它也是忽略routingKey的一 ...
- (转)RabbitMQ学习之主题topic(java)
http://blog.csdn.net/zhu_tianwei/article/details/40887775 参考:http://blog.csdn.NET/lmj623565791/artic ...
- (转)RabbitMQ学习之路由(java)
http://blog.csdn.net/zhu_tianwei/article/details/40887755 参考:http://blog.csdn.NET/lmj623565791/artic ...
- (转) RabbitMQ学习之发布/订阅(java)
http://blog.csdn.net/zhu_tianwei/article/details/40887733 参考:http://blog.csdn.NET/lmj623565791/artic ...
- RabbitMQ学习第二记:工作队列的两种分发方式,轮询分发(Round-robin)和 公平分发(Fair dispatch)
1.什么是RabbitMQ工作队列 我们在应用程序使用消息系统时,一般情况下生产者往队列里插入数据时速度是比较快的,但是消费者消费数据往往涉及到一些业务逻辑处理导致速度跟不上生产者生产数据.因此如果一 ...
- RabbitMQ学习总结 第二篇:快速入门HelloWorld
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- RabbitMQ学习总结 第四篇:发布/订阅 Publish/Subscribe
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
随机推荐
- 用 Vue 做一个简单的购物app
前言 最近在学习Vue的使用.看了官方文档之后,感觉挺有意思的.于是着手做了一个简单的购物app.h5 与原生 app 交互的原理这是我第一次在这个网站上写分享,如有不当之处,请多多指教. 一整个项目 ...
- Golang - 处理字符串
目录 Golang - 处理字符串 1. 字符串操作 2. 字符串转换 Golang - 处理字符串 1. 字符串操作 func Contains(s, substr string) bool 字符串 ...
- UVa - 11283 - PLAYING BOGGLE
先上题目 Problem F PLAYING BOGGLE Boggle® is a classic word game played on a 4 by 4 grid of letters. The ...
- ArcEngine 地图导航 查找路径 经纬度坐标导航 最优路径分析
本文来自CSDN博客.转载请标明出处 http//blog.csdn.net/zdb330906531 需求:依据经纬度坐标.取得两个起点与终点,显示最优路径实现导航. 參考官方样例后.我在arcMa ...
- RecyclerView的使用(1)之HelloWorld
原创文章.转载请注明 http://blog.csdn.net/leejizhou/article/details/50670657 RecyclerView是伴随Android 5.0公布的新控件, ...
- Java学习需要掌握的一些知识
Java学习需要掌握的一些知识: <一>1.Jvm 部分Jvm 内存模型.Jvm 内存结构.Jvm 参数调优.Java 垃圾回收<二>Java 基础部分1.必须会使用 List ...
- Chrome Extension 的 webRequest模块的解读
Chrome Extension 的 webRequest模块的解读 文档在此:http://developer.chrome.com/trunk/extensions/webRequest.ht ...
- H3C子接口配置要点及实例说明
类型一:以太网子接口配置要点(单臂路由) 第一步:在路由器对端的交换机上配置好vlan信息(如vlan10/vlan20) 第二步:将交换机上与路由器直接相连的以太口配置成trunk口并同意 ...
- 项目产品化——Excel数据库模板化导入(java)
Excel导入可能是代码开发中比較常见的功能,一个项目假设有多个地方须要excel导入数据库.那么开发的工作量也将比較大,项目产品化过程中,将这么一个类似的功能进行封装合并也是必要的.封装好的代码仅仅 ...
- linux下的开源移动图像监测程序--motion编译与配置【转】
本文转载自:http://www.cnblogs.com/qinyg/p/3355707.html 前几天在网上偶然看到一篇博客,是利用linxu下的开源的motion搭建嵌入式视频动态监控系统,感觉 ...