rabbitmq学习记录
一、RabbitMQ的概念
RabbitMQ 是一个消息中间件:它接受并转发消息。你可以把它当做一个快递站点,当你要发送一个包裹时,你把你的包裹放到快递站,快递员最终会把你的快递送到收件人那里,按照这种逻辑 RabbitMQ 是一个快递站,一个快递员帮你传递快件。RabbitMQ 与快递站的主要区别在于:它不处理快件而是接收,存储和转发消息数据。
二、四大核心概念
生产者:产生数据发送消息的程序是生产者。
交换机:交换机是 RabbitMQ 非常重要的一个部件,一方面它接收来自生产者的消息,另一方面它将消息推送到队列中。交换机必须确切知道如何处理它接收到的消息,是将这些消息推送到特定队列还是推送到多个队列,亦或者是把消息丢弃,这个是由交换机类型决定的。
队列:队列是 RabbitMQ 内部使用的一种数据结构,尽管消息流经 RabbitMQ 和应用程序,但它们只能存储在队列中。队列仅受主机的内存和磁盘限制的约束,本质上是一个大的消息缓冲区。许多生产者可以将消息发送到一个队列,许多消费者可以尝试从一个队列接收数据。
消费者:消费与接收具有相似的含义。消费者大多时候是一个等待接收消息的程序。请注意生产者,消费者和消息中间件很多时候并不在同一机器上。同一个应用程序既可以是生产者又是可以是消费者。
三、可视化页面解读
1、用户操作
- 默认会提供一个默认用户guest,密码也是guest,线上环境需要创建一个新用户,并把guest用户删除。
- 首先切换到Admin标签页,可以查看或添加用户,添加用户时,可指定Tags,相当于角色,会拥有对应的权限:

部分权限解释:
none:不能访问 management plugin
management:
- 查看自己相关节点信息
- 列出自己可以通过AMQP登入的虚拟机
- 查看自己的虚拟机节点virtual hosts的queues,exchanges和bindings信息
- 查看和关闭自己的channels和connections
- 查看有关自己的虚拟机节点virtual hosts的统计信息。包括其他用户在这个节点virtual hosts中的活动信息
Policymaker
- 包含management所有权跟
- 查看和创建和删除自己的virtual hosts所属的policies和parameters信息
Monitoring
- 包含management所有权限
- 罗列出所有的virtual hosts,包括不能登录的virtual hosts
- 查看其他用户的connections和channels信息
- 查看节点级别的数据如clustering和memory使用情况
- 查看所有的virtual hosts的全局统计信息。
Administrator
- 最高权限
- 可以创建和删除 virtual hosts
- 可以查看,创建和删除users
- 查看创建permissions
- 关闭所有用户的connections
2、交换机操作
切换到“Exchanges”标签,可查看和管理交换器,单击交换器名称,可查看到更多详细信息,比如交换器绑定,还可以添加新的绑定


3、队列
切换到“Queues”标签,可以查看队列信息,点击队列名称,可查看队列所有状态的消息数量和大小等统计信息:



四、体验RabbitMQ
1、因为我用的是SpringBoot,所以在生产者这边加入对应的依赖即可:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2、包结构(个人):

3、在application.yml文件加上RabbitMQ的配置信息:
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
#这个配置是保证提供者确保消息推送到交换机中,不管成不成功,都会回调
publisher-confirm-type: correlated
#保证交换机能把消息推送到队列中
publisher-returns: true
virtual-host: /
4、创建一个Direct交换机以及队列的配置类:
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* @author wjx
*/
@Configuration
public class RabbitMqConfig { //队列1
@Bean
public Queue Queue1() {
/**
* 1、name: 队列名称
* 2、durable: 是否持久化
* 3、exclusive: 是否独享、排外的。如果设置为true,定义为排他队列。则只有创建者可以使用此队列。也就是private私有的。
* 4、autoDelete: 是否自动删除。也就是临时队列。当最后一个消费者断开连接后,会自动删除。
* */
return new Queue("Queue1", true,true,false);
} //队列2
@Bean
public Queue Queue2() {
/**
* 1、name: 队列名称
* 2、durable: 是否持久化
* 3、exclusive: 是否独享、排外的。如果设置为true,定义为排他队列。则只有创建者可以使用此队列。也就是private私有的。
* 4、autoDelete: 是否自动删除。也就是临时队列。当最后一个消费者断开连接后,会自动删除。
* */
return new Queue("Queue2", true,true,false);
} //DirectExchange交换机
@Bean
public DirectExchange DirectExchange() {
/**
* 1、name: 交换机名称
* 2、durable: 是否持久化
* 3、autoDelete: 是否自动删除。也就是临时交换机。当最后一个消费者断开连接后,会自动删除。
* */
return new DirectExchange("DirectExchange",true,false);
} //FanoutExchange交换机
@Bean
public FanoutExchange FanoutExchange() {
/**
* 1、name: 交换机名称
* 2、durable: 是否持久化
* 3、autoDelete: 是否自动删除。也就是临时交换机。当最后一个消费者断开连接后,会自动删除。
* */
return new FanoutExchange("FanoutExchange",true,false);
} //TopicExchange交换机
@Bean
public TopicExchange TopicExchange() {
/**
* 1、name: 交换机名称
* 2、durable: 是否持久化
* 3、autoDelete: 是否自动删除。也就是临时交换机。当最后一个消费者断开连接后,会自动删除。
* */
return new TopicExchange("TopicExchange",true,false);
}
//---测试DirectExChange交换机
//绑定交换机、队列、路由key关系
@Bean
public Binding Binding1() {
return BindingBuilder
.bind(Queue1())
.to(DirectExchange())
.with("routingKey1");
}
//绑定交换机、队列、路由key关系
@Bean
public Binding Binding2() {
return BindingBuilder
.bind(Queue2())
.to(DirectExchange())
.with("routingKey2");
}
//---测试FanoutExChange交换机
//绑定交换机、队列、路由key关系
// @Bean
// public Binding Binding1() {
// return BindingBuilder
// .bind(Queue1())
// .to(FanoutExChange());
// }
// //绑定交换机、队列、路由key关系
// @Bean
// public Binding Binding2() {
// return BindingBuilder
// .bind(Queue2())
// .to(FanoutExChange());
// }
//----测试TopicExChange类型交换机
//绑定交换机、队列、路由key关系
// @Bean
// public Binding Binding1() {
// return BindingBuilder
// .bind(Queue1())
// .to(TopicExchange())
// .with("*.orange.*");
// } //绑定交换机、队列、路由key关系
// @Bean
// public Binding Binding2() {
// return BindingBuilder
// .bind(Queue2())
// .to(TopicExchange())
// .with("*.*.rabbit");
// }
//绑定交换机、队列、路由key关系
// @Bean
// public Binding Binding3() {
// return BindingBuilder
// .bind(Queue2())
// .to(TopicExchange())
// .with("lazy.#");
// }
}
5、创建一个发送消息的VO类:
@Data
public class MsgSendVO implements Serializable { private static final long serialVersionUID = 5905249092659173678L; private String priKey; private String businessType; private String phoneNum; private String msg; }
6、创建一个发送消息的生产者类:
/**
* @author wjx
*/
@Slf4j
@Service
public class MsgProducer {
@Resource
private RabbitTemplate rabbitTemplate; //测试Direct
public void sendDirectExchange(MsgSendVO msgSendVO) {
log.info("生产消息【{}】"+msgSendVO);
rabbitTemplate.convertAndSend("DirectExchange",
"routingKey1", msgSendVO);
rabbitTemplate.convertAndSend("DirectExchange",
"routingKey2", msgSendVO);
} //Fanout
public void sendFanoutExchange(MsgSendVO msgSendVO) {
log.info("生产消息【{}】"+msgSendVO);
rabbitTemplate.convertAndSend("FanoutExchange",
null,msgSendVO);
} //Topic
public void sendTopicExchange(MsgSendVO msgSendVO) {
log.info("生产消息【{}】"+msgSendVO);
rabbitTemplate.convertAndSend("TopicExchange",
"quick.orange.rabbit", msgSendVO);
}
}
7、创建一个消费消息的消费者类:
/**
* @author 71561
*/
@Component
@Slf4j
public class MsgConsumer {
//监听消息队列Queue1
@RabbitListener(queues = {"Queue1"})
public void msgSend(MsgSendVO vo) {
System.out.println("消费者1收到消息:"+vo);
}
//监听消息队列Queue2
@RabbitListener(queues = {"Queue2"})
public void getMag(MsgSendVO vo) {
System.out.println("消费者2收到消息:"+vo);
}
}
8、然后根据业务放在需要用的地方,比如定时任务,或者接口。我这里就简单一点使用Controller层进行发送:
/**
* @author 71561
*/
@RestController
@RequestMapping("/mq")
public class TestMqController {
@Resource
private MsgProducer notifyMsgProducer; @GetMapping("/produce")
public String produce() {
MsgSendVO vo = new MsgSendVO();
vo.setPriKey(UUID.randomUUID().toString());
vo.setPhoneNum("191xxxxxxxx");
vo.setBusinessType("msg_send");
vo.setMsg("大帅哥");
//测试Direct
notifyMsgProducer.sendDirectExchange(vo);
//Fanout
// notifyMsgProducer.sendFanoutExchange(vo);
//Topic
// notifyMsgProducer.sendTopicExchange(vo);
return "success";
} }
五、认识交换机
1 Exchanges概念
RabbitMQ 消息传递模型的核心思想是: 生产者生产的消息从不会直接发送到队列。实际上,通常生产 者甚至都不知道这些消息传递传递到了哪些队列中。
相反,生产者只能将消息发送到交换机(exchange),交换机工作的内容非常简单,一方面它接收来自生产者的消息,另一方面将它们推入队列。交换机必须确切知道如何处理收到的消息。是应该把这些消息放到特定队列还是说把他们到许多队列中还是说应该丢弃它们。这就的由交换机的类型来决定。
2 Exchanges的类型
Exchanges总共有以下类型
- 直接(direct)
- 主题(topic)
- 标题(header)
- 扇出(fanout)
3 、绑定(bindings)
什么是 bingding 呢,binding 其实是 exchange 和 queue 之间的桥梁,它告诉我们 exchange 和那个队 列进行了绑定关系。比如说下面这张图告诉我们的就是 X 与 Q1 和 Q2 进行了绑定

4、Direct类型队列介绍
bindings中绑定是交换机和队列之间的桥梁关系。也可以理解为: 队列只对它绑定的交换机的消息感兴趣。绑定用参数:routingKey 来表示也可称该参数为 binding key

5、Fanout类型队列介绍
Fanout 类型。它是将接收到的所有消息广播到它知道的 所有队列中。系统中默认有些exchange 类型
6、Topic类型队列介绍
发送到类型是 topic 交换机的消息的 routing_key 不能随意写,必须满足一定的要求,它必须是一个单词列表,以点号分隔开。这些单词可以是任意单词,比如说:“stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”.这种类型的。当然这个单词列表最多不能超过 255 个字节。
在这个规则列表中,其中有两个替换符是大家需要注意的
*(星号)可以代替一个单词
#(井号)可以替代零个或多个单词

如上图所示
Q1队列绑定的是* .orange. * ,表示中间带 orange 带 3 个单词的字符串( * .orange. )
Q2队列绑定的是*. *.rabbit和lazy.#
*最后一个单词是 rabbit 的 3 个单词(*. .rabbit)
六、小知识
Feign和MQ的区别
- feign采用同步调用方式,具有时效性强等优点,但是性能低、吞吐量下降、耦合度高容易导致级联失败等缺点
- MQ采用异步调用方式,具有性能高、吞吐量高、解耦合、流量削峰、故障隔离等优点;但是也存在架构复杂、业务没有明显流程线、跟踪管理困难、强烈依靠Broker的可靠性等缺点
在微服务项目中,假如有两个微服务项目 查询价格 和 修改价格, 修改了价格之后,需要在查询库中同步更新价格. feign是同步的,所以会增加等待时间. rabbitmq是异步通信,这就是它们的主要区别.
rabbitmq学习记录的更多相关文章
- 【RabbitMQ学习记录】- 消息队列存储机制源码分析
本文来自 网易云社区 . RabbitMQ在金融系统,OpenStack内部组件通信和通信领域应用广泛,它部署简单,管理界面内容丰富使用十分方便.笔者最近在研究RabbitMQ部署运维和代码架构,本篇 ...
- RabbitMQ学习记录1
前言 我是在解决分布式事务的一致性问题时了解到RabbitMQ的,当时主要是要基于RabbitMQ来实现我们分布式系统之间对有事务可靠性要求的系统间通信的.关于分布式事务一致性问题及其常见的解决方案, ...
- 1.Rabbitmq学习记录《本质介绍,协议AMQP分析》
1.RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现. RabbitMQ的优势-: 除了Qpid,RabbitMQ是唯一一个实现了AMQP ...
- RabbitMQ 学习记录
rabbit mq知识点:1.消费时可以通过acknowledge设定消费是否成功,消费不成功时在server端requeue2.需要注意两个持久化:queue持久化和消息持久化(通过代码设定,默认即 ...
- RabbitMQ上手记录–part 2 - 安装RabbitMQ
上一篇<<RabbitMQ 上手记录-part 1>>介绍了一些基础知识,整理了一些基础概念.接下来整理一些安装步骤和遇到的问题. 我在CentOS7和Ubuntu16.4上都 ...
- RabbitMQ学习系列二-C#代码发送消息
RabbitMQ学习系列二:.net 环境下 C#代码使用 RabbitMQ 消息队列 http://www.80iter.com/blog/1437455520862503 上一篇已经讲了Rabbi ...
- Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群
Redis总结(五)缓存雪崩和缓存穿透等问题 前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...
- 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ
鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...
- RabbitMQ学习系列(四): 几种Exchange 模式
上一篇,讲了RabbitMQ的具体用法,可以看看这篇文章:RabbitMQ学习系列(三): C# 如何使用 RabbitMQ.今天说些理论的东西,Exchange 的几种模式. AMQP协议中的核心思 ...
- RabbitMQ学习系列(三): C# 如何使用 RabbitMQ
上一篇已经讲了Rabbitmq如何在Windows平台安装,还不了解如何安装的朋友,请看我前面几篇文章:RabbitMQ学习系列一:windows下安装RabbitMQ服务 , 今天就来聊聊 C# 实 ...
随机推荐
- STC8A8K64S4A12内部时钟的IRTRIM和LIRTRIM简单标定
STC8A8K64S4A12因为没有固化的频率调节值, 要么在STC-ISP烧录时设置写入, 要么通过idata高地址读取, 这对于Linux下的SDCC用户就非常不方便, 既不能用STC-ISP, ...
- 端口碰撞Port Knocking和单数据包授权SPA
端口碰撞技术 Port knocking 从网络安全的角度,服务器开启的端口越多就越不安全,因此系统安全加固服务中最常用的方式,就是先关闭无用端口,再对提供服务的端口做访问控制.而作为远程管理与维护的 ...
- UML类图入门实战
介绍 UML--Unified modeling language UML (统一建模语言),是一种用于软件系统分析和设计的语言工具,它用于帮助软件开发人员进行思考和记录思路的结果. UML 本身是一 ...
- Javascript操作对象数组实现增删改查
1.介绍 最近帮朋友弄一个简单的针对json数组的增删改成页面,正好涉及到了js去操作对象数组实现增删改查功能.我估计很多朋友应该也会遇到这类操作,所以记录一下以便分享. 2.数据准备 这里我就以学生 ...
- MySQL的随机排序(random orderby)
MySQL的随机排序(random orderby)是指在查询数据库时,将结果集以随机的方式排列.这种排序方式可以用于有趣的应用场景,例如实现随机音乐播放.广告推荐等. 要实现MySQL的随机排序,可 ...
- 硬件开发笔记(二):硬件开发基本流程,制作一个USB转RS232的模块(一):开发基本过程和元器件选型
前言 做个usb转串口,同时兼容ttl,讲述硬件模块基础的开发流程,本篇描述了全流程过程,然后选型了合适的元器件. 基本流程 以下是笔者个人从事过相关硬件研发,总结出来的流程,仅代表个人意 ...
- 用BootstrapBlazor制作修改订单字段的页面
1.在Shared文件夹下新增一个razor 2.页面初始化的时候获取订单信息 准备一个名为OrderId的参数 准备重写页面初始化时的方法 改成异步的形式来重写 4.获取数据 就3行代码. 声明这个 ...
- DataGear 使用静态HTML模板制作数据可视化看板
DataGear 看板提供了导入静态 HTML 模板的功能,使您可以利用已有的任意 HTML 网页资源快速制作数据可视化看板. 首先,您需要准备一套已设置好布局的静态 HTML 模板,其中包含的 HT ...
- 【Azure 应用服务】应用代码中需要使用客户端证书访问服务接口,部署在应用服务后报错不能找到证书(Cannot find the X.509 certificate)
问题描述 在应用中,需要访问另一个服务接口,这个接口需要使用客户端证书进行认证.在代码中使用 System.Security.Cryptography.X509Certificates 加载Windo ...
- 【Azure API 管理】APIM Self-Host Gateway 自建本地环境中的网关数量超过10个且它们的出口IP为同一个时出现的429错误
问题描述 Azure API Management服务支持使用自建网关来实现API服务,这样APIM的所有请求都可以走在自管理的企业内网中.流量都更加安全.当根据官网文档搭建后,如果在本地环境中部署超 ...