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 ...
随机推荐
- IDEA 创建git 分支 拉取分支
此时只是在本地创建好了分支,修改源代码后add,commit将本地分支提交到远程仓库 分支已创建,其它成员此时就可以从git拉分支
- (笔记)Linux服务器中判断客户端socket断开连接的方法
下面来罗列一下判断远端已经断开的方法:(转自http://blog.csdn.net/god2469/article/details/8801356) 法一: 当recv()返回值小于等于0时,soc ...
- 三个支持正则表达式的行处理的工具: grep/sed/awk
grep: 全称Global Regular Expression Print, 是干什么的,不多说了: 用法:grep [-options] [pattern] [filename] 选项: -c: ...
- 正则split
string content = "第1行导入失败,失败原因为: <加班原因>字段必填"; string[] resultString = Regex.Split(co ...
- C# 校验给定的ip地址是否合法
函数用于检测ip地址格式是否合法,包括ip的组成格式,每隔段是否不超过255等,但这个函数不能验证这个ip地址是否可以ping通. /// <summary> /// 验证IP地址是否合法 ...
- vi编辑器的使用方式
vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令.由于对Unix及Linux系统的任何版本,vi编辑器是完全相 ...
- jmm 和线程安全
Java的内存模型JMM Java的内存模型JMM(Java Memory Model)JMM主要是为了规定了线程和内存之间的一些关系.根据JMM的设计,系统存在一个主内存(Main Memory), ...
- 关于ARM NEON学习的一些资料
在对基于ARM-v7处理器及以上的程序进行优化时,可以使用neon优化技术来加速程序.不过搞这个的人比较少,所以网上有用的资料很稀少.我翻了半天国内国外的博客,发现还是ARM公司的帮助网站最有用: h ...
- Android学习之——切换应用主题实现日间和夜间效果的更换
前言 智能手机的迅速普及,大大的丰富了我们的娱乐生活.现在大家都喜欢晚上睡觉前玩会儿手机,但是应用的日间模式往往亮度太大,对眼睛有较为严重的伤害. 因此,如今的应用往往开发了日间和夜间两种模式供用户切 ...
- android LinearLayout添加分隔线
方法一: 可以放置一个ImageView组件,然后将其设为分隔线的颜色或图形. 分隔线View的定义代码如下: [html] view plaincopy <ImageView androi ...