RabbitMQ之总结
P:生成者,消息产生者;
C:消息消费者;
红:消息队列;
- java实现
步骤:
- 创建连接
- 从连接中创建通道(相当于JDBC中的Statement)
- 通过channel声明(创建)队列。(如果队列存在,则返回,如果不存在,则创建队列)
- 向队列中发送消息;
- 关闭连接和通道。
package com.j1.rabbitmq.simple; import com.j1.rabbitmq.util.ConnectionUtil; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; public class Send { private final static String QUEUE_NAME = "test_queue"; public static void main(String[] argv) throws Exception { // 获取到连接以及mq通道 Connection connection = ConnectionUtil.getConnection(); // 从连接中创建通道 Channel channel = connection.createChannel(); // 声明(创建)队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 消息内容 String message = "Hello World! 1111"; channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); System.out.println(" [x] Sent '" + message + "'"); //关闭通道和连接 channel.close(); connection.close(); } }
package com.j1.rabbitmq.simple; import com.j1.rabbitmq.util.ConnectionUtil; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.QueueingConsumer; public class Recv { private final static String QUEUE_NAME = "test_queue"; public static void main(String[] argv) throws Exception { // 获取到连接以及mq通道 Connection connection = ConnectionUtil.getConnection(); Channel channel = connection.createChannel(); // 声明队列 /** * 如果队列存在,则返回,如果不存在,则创建 */ channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 定义队列的消费者 QueueingConsumer consumer = new QueueingConsumer(channel); // 监听队列 channel.basicConsume(QUEUE_NAME, true, consumer); // 获取消息 while (true) { QueueingConsumer.Delivery delivery = consumer.nextDelivery(); String message = new String(delivery.getBody()); System.out.println(" [x] Received '" + message + "'"); } } }
- 工作模式
一个生成者,多个消费者。
- 生产者
package com.j1.rabbitmq.work; import com.j1.rabbitmq.util.ConnectionUtil; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; public class Send { private final static String QUEUE_NAME = "test_queue_work"; public static void main(String[] argv) throws Exception { // 获取到连接以及mq通道 Connection connection = ConnectionUtil.getConnection(); Channel channel = connection.createChannel(); // 声明队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); for (int i = 0; i < 100; i++) { // 消息内容 String message = "" + i; channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); System.out.println(" [x] Sent '" + message + "'"); Thread.sleep(i * 10); } channel.close(); connection.close(); } }
消费者1
package com.j1.rabbitmq.work; import com.j1.rabbitmq.util.ConnectionUtil; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.QueueingConsumer; public class Recv { private final static String QUEUE_NAME = "test_queue_work"; public static void main(String[] argv) throws Exception { // 获取到连接以及mq通道 Connection connection = ConnectionUtil.getConnection(); Channel channel = connection.createChannel(); // 声明队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 同一时刻服务器只会发一条消息给消费者,每一次服务器只会向客户端发送一条 //channel.basicQos(1); // 定义队列的消费者 QueueingConsumer consumer = new QueueingConsumer(channel); // 监听队列,手动返回完成 channel.basicConsume(QUEUE_NAME, false, consumer); // 获取消息 while (true) { QueueingConsumer.Delivery delivery = consumer.nextDelivery(); String message = new String(delivery.getBody()); System.out.println(" [x] Received '" + message + "'"); //休眠 Thread.sleep(10); // 返回确认状态 channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); } } }
消费者2
package com.j1.rabbitmq.work; import com.j1.rabbitmq.util.ConnectionUtil; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.QueueingConsumer; public class Recv2 { private final static String QUEUE_NAME = "test_queue_work"; public static void main(String[] argv) throws Exception { // 获取到连接以及mq通道 Connection connection = ConnectionUtil.getConnection(); Channel channel = connection.createChannel(); // 声明队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 同一时刻服务器只会发一条消息给消费者,每一次服务器只会向客户端发送一条 // channel.basicQos(1); // 定义队列的消费者 QueueingConsumer consumer = new QueueingConsumer(channel); // 监听队列,手动返回完成状态 channel.basicConsume(QUEUE_NAME, false, consumer); // 获取消息 while (true) { QueueingConsumer.Delivery delivery = consumer.nextDelivery(); String message = new String(delivery.getBody()); System.out.println(" [x] Received '" + message + "'"); // 休眠1秒 Thread.sleep(1000); channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); } } }
- 测试
消费者1:
消费者2:
- 结论
无论消费者处理消息的速度如何,获取到的消息数量是一致的,这样并不合理,应该是能者多劳,多劳多得。
- 设置每次只向客户端发送一条消息
// 同一时刻服务器只会发一条消息给消费者,每一次服务器只会向客户端发送一条 channel.basicQos(1);
- 结论
这种模式更符合实际项目需要。
- 订阅模式
一个生成者,多个消费者,每个消费者获取到的消息是一样的。
1、生成者发送消息到交换机。(生产者可以向队列或者交换机发送消息)
2、消费者监听消息队列,消费者永远只能从队列中获取消息。
3、队列绑定到交换机,获取消息。
- 发送消息
- 消费者
将队列绑定到交换机,如果不绑定是获取不到消息的。
后面还有
- 路由模式
- 通配符模式
这里就不在一一详述了,在工作中主要是用订阅模式.
RabbitMQ之总结的更多相关文章
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- RabbitMq应用二
在应用一中,基本的消息队列使用已经完成了,在实际项目中,一定会出现各种各样的需求和问题,rabbitmq内置的很多强大机制和功能会帮助我们解决很多的问题,下面就一个一个的一起学习一下. 消息响应机制 ...
- 如何优雅的使用RabbitMQ
RabbitMQ无疑是目前最流行的消息队列之一,对各种语言环境的支持也很丰富,作为一个.NET developer有必要学习和了解这一工具.消息队列的使用场景大概有3种: 1.系统集成,分布式系统的设 ...
- RabbitMq应用一的补充(RabbitMQ的应用场景)
直接进入正题. 一.异步处理 场景:发送手机验证码,邮件 传统古老处理方式如下图 这个流程,全部在主线程完成,注册->入库->发送邮件->发送短信,由于都在主线程,所以要等待每一步完 ...
- RabbitMq应用一
RabbitMq应用一 RabbitMQ的具体概念,百度百科一下,我这里说一下我的理解,如果有少或者不对的地方,欢迎纠正和补充. 一个项目架构,小的时候,一般都是传统的单一网站系统,或者项目,三层架构 ...
- 缓存、队列(Memcached、redis、RabbitMQ)
本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...
- 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)
Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...
- windows下 安装 rabbitMQ 及操作常用命令
rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...
- RabbitMQ + PHP (三)案例演示
今天用一个简单的案例来实现 RabbitMQ + PHP 这个消息队列的运行机制. 主要分为两个部分: 第一:发送者(publisher) 第二:消费者(consumer) (一)生产者 (创建一个r ...
- RabbitMQ + PHP (二)AMQP拓展安装
上篇说到了 RabbitMQ 的安装. 这次要在讲案例之前,需要安装PHP的AMQP扩展.不然可能会报以下两个错误. 1.Fatal error: Class 'AMQPConnection' not ...
随机推荐
- dd&win32diskimager&软碟通Ultraiso 简单分析区别和长处
在linux操作系统之中的话我们希望烧录镜像到U盘或者是其他的可移动存储设备的话,那么我们就是应当使用dd,但是我估量 在我们的论坛之中根本 之上只有很少的人使用这种工具,很多的使用linux的用户都 ...
- (原创)Linux下的floating point exception错误解析
很多人也许都碰到过这样的错误:linux下程序刚一运行就报错:Floating point exception. 其实这个问题很容易排查,绝大多数情况情况都是逻辑的问题,如:c = a/b;或 c = ...
- (笔记)Linux下检测网卡与网线连接状态
http://blog.chinaunix.net/space.php?uid=20357359&do=blog&cuid=1798479 Linux下检测网卡与网线连接状态,使用io ...
- 第三百四十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫数据保存
第三百四十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫数据保存 注意:数据保存的操作都是在pipelines.py文件里操作的 将数据保存为json文件 spider是一个信号检测 ...
- 导入Maven项目后,Eclipse提示“Missing artifact ”类的错误
导入Maven项目后,Eclipse提示“Missing artifact ”类的错误 标签: Maven Missing art 2016-08-15 16:05 679人阅读 评论(0) 收藏 举 ...
- python_装饰器模式
装饰器模式定义:动态地给一个对象添加一些额外的职责. 在Python中Decorator mode可以按照像其它编程语言如C++, Java等的样子来实现,但是Python在应用装饰概念方面的能力上远 ...
- T4使用经验
.<#@ template debug="true" hostspecific="true" language="C#" #> ...
- iOS: 自动增高的 textView
如 iPhone 内应用“信息”的输入框一样,输入文字过多或者输入换行,输入框可以随着内容自动变化.主要是计算内容的尺寸并相应更改输入框的frame.具体表现在: 更改输入框的 frame.origi ...
- ubuntu 4.10~5.10 :古老的ubuntu上安装oracle10g的情况
64位的: 不用想了,安装不上,因为ubuntu库里没有提供编译环境:安装不上gcc-multilib库.也没有libc6-dev-i386库! 自己这点水平,真搞不定! 32位的: 很顺利.很顺利! ...
- linux系统负载
系统负载System Load:系统CPU繁忙程度的度量,即有多少进程在等待被CPU调度 平均负载(Load Average):一段时间内系统的平均负载,这个一段时间一般取1分钟.5分钟.15分钟 查 ...