(转) 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学习总结 ...
随机推荐
- Django1.11配合uni-app发起微信支付!
Django1.11配合uni-app发起微信支付! 经过三天的断断续续的奋战,我终于是干动了微信支付.为了以后不忘记,现在来一篇教程,来来来,开干!!! 一.准备阶段 1.准备阶段我们需要去微信官网 ...
- 认识计算机操作系统(day01)
一.计算机的框架 什么是操作系统?(汽车) 加油系统 油门 用户跟加油子系统交互的窗口.(接口) 方向系统 方向盘 用户跟方向系统的交互接口. 导航系统 ... 汽车的操作系统有很多的子系统来完成.这 ...
- 爬取表格类网站数据并保存为excel文件
本文转载自以下网站:50 行代码爬取东方财富网上市公司 10 年近百万行财务报表数据 https://www.makcyun.top/web_scraping_withpython6.html 主要学 ...
- BeanUtils.copyProperties()错误使用,给自己挖了坑
场景:需要对某个集合中的所有元素拷贝到另一个集合中,想着BeanUtils.copyProperties()可以深拷贝对象,误以为也可以拷贝集合,于是乎写下了如下代码 List<CostRule ...
- BZOJ 3930 Luogu P3172 选数 (莫比乌斯反演)
手动博客搬家:本文发表于20180310 11:46:11, 原地址https://blog.csdn.net/suncongbo/article/details/79506484 题目链接: (Lu ...
- (35)Spring Boot集成Redis实现缓存机制【从零开始学Spring Boot】
[本文章是否对你有用以及是否有好的建议,请留言] 本文章牵涉到的技术点比较多:Spring Data JPA.Redis.Spring MVC,Spirng Cache,所以在看这篇文章的时候,需要对 ...
- 手动搭建HTTP下载站点
手动搭建HTTP下载站点 index.jsp <%--Listfile.jsp--%> <%@ page import="java.io.File,java.text.Si ...
- codechef Little Elephant and Bombs题解
The Little Elephant from the Zoo of Lviv currently is on the military mission. There are N enemy bui ...
- 各种JSON的maven引用
一.jackjson maven <jackjson.version>2.8.8</jackjson.version> <dependency> <group ...
- linux中udev简单的用法【转】
本文转载自:http://blog.csdn.net/qq_29729577/article/details/50825134 udev是Linux提供的一种在用户态管理设备的一种机制,udev的详细 ...