一、RabbitMQ的概念

RabbitMQ 是一个消息中间件:它接受并转发消息。你可以把它当做一个快递站点,当你要发送一个包裹时,你把你的包裹放到快递站,快递员最终会把你的快递送到收件人那里,按照这种逻辑 RabbitMQ 是一个快递站,一个快递员帮你传递快件。RabbitMQ 与快递站的主要区别在于:它不处理快件而是接收,存储和转发消息数据。

二、四大核心概念

生产者:产生数据发送消息的程序是生产者。

交换机:交换机是 RabbitMQ 非常重要的一个部件,一方面它接收来自生产者的消息,另一方面它将消息推送到队列中。交换机必须确切知道如何处理它接收到的消息,是将这些消息推送到特定队列还是推送到多个队列,亦或者是把消息丢弃,这个是由交换机类型决定的。

队列:队列是 RabbitMQ 内部使用的一种数据结构,尽管消息流经 RabbitMQ 和应用程序,但它们只能存储在队列中。队列仅受主机的内存和磁盘限制的约束,本质上是一个大的消息缓冲区。许多生产者可以将消息发送到一个队列,许多消费者可以尝试从一个队列接收数据。

消费者:消费与接收具有相似的含义。消费者大多时候是一个等待接收消息的程序。请注意生产者,消费者和消息中间件很多时候并不在同一机器上。同一个应用程序既可以是生产者又是可以是消费者。

三、可视化页面解读

1、用户操作

  1. 默认会提供一个默认用户guest,密码也是guest,线上环境需要创建一个新用户,并把guest用户删除。
  2. 首先切换到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总共有以下类型

  1. 直接(direct)
  2. 主题(topic)
  3. 标题(header)
  4. 扇出(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的区别

  1. feign采用同步调用方式,具有时效性强等优点,但是性能低、吞吐量下降、耦合度高容易导致级联失败等缺点
  2. MQ采用异步调用方式,具有性能高、吞吐量高、解耦合、流量削峰、故障隔离等优点;但是也存在架构复杂、业务没有明显流程线、跟踪管理困难、强烈依靠Broker的可靠性等缺点

在微服务项目中,假如有两个微服务项目 查询价格 和 修改价格, 修改了价格之后,需要在查询库中同步更新价格. feign是同步的,所以会增加等待时间. rabbitmq是异步通信,这就是它们的主要区别.

rabbitmq学习记录的更多相关文章

  1. 【RabbitMQ学习记录】- 消息队列存储机制源码分析

    本文来自 网易云社区 . RabbitMQ在金融系统,OpenStack内部组件通信和通信领域应用广泛,它部署简单,管理界面内容丰富使用十分方便.笔者最近在研究RabbitMQ部署运维和代码架构,本篇 ...

  2. RabbitMQ学习记录1

    前言 我是在解决分布式事务的一致性问题时了解到RabbitMQ的,当时主要是要基于RabbitMQ来实现我们分布式系统之间对有事务可靠性要求的系统间通信的.关于分布式事务一致性问题及其常见的解决方案, ...

  3. 1.Rabbitmq学习记录《本质介绍,协议AMQP分析》

    1.RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现. RabbitMQ的优势-: 除了Qpid,RabbitMQ是唯一一个实现了AMQP ...

  4. RabbitMQ 学习记录

    rabbit mq知识点:1.消费时可以通过acknowledge设定消费是否成功,消费不成功时在server端requeue2.需要注意两个持久化:queue持久化和消息持久化(通过代码设定,默认即 ...

  5. RabbitMQ上手记录–part 2 - 安装RabbitMQ

    上一篇<<RabbitMQ 上手记录-part 1>>介绍了一些基础知识,整理了一些基础概念.接下来整理一些安装步骤和遇到的问题. 我在CentOS7和Ubuntu16.4上都 ...

  6. RabbitMQ学习系列二-C#代码发送消息

    RabbitMQ学习系列二:.net 环境下 C#代码使用 RabbitMQ 消息队列 http://www.80iter.com/blog/1437455520862503 上一篇已经讲了Rabbi ...

  7. Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群

    Redis总结(五)缓存雪崩和缓存穿透等问题   前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...

  8. 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ

    鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...

  9. RabbitMQ学习系列(四): 几种Exchange 模式

    上一篇,讲了RabbitMQ的具体用法,可以看看这篇文章:RabbitMQ学习系列(三): C# 如何使用 RabbitMQ.今天说些理论的东西,Exchange 的几种模式. AMQP协议中的核心思 ...

  10. RabbitMQ学习系列(三): C# 如何使用 RabbitMQ

    上一篇已经讲了Rabbitmq如何在Windows平台安装,还不了解如何安装的朋友,请看我前面几篇文章:RabbitMQ学习系列一:windows下安装RabbitMQ服务 , 今天就来聊聊 C# 实 ...

随机推荐

  1. springboot 实现拦截的 3 种方式介绍及异步执行的思考

    springboot 拦截方式 实际项目中,我们经常需要输出请求参数,响应结果,方法耗时,统一的权限校验等. 本文首先为大家介绍 HTTP 请求中三种常见的拦截实现,并且比较一下其中的差异. (1)基 ...

  2. ckeditor实战总结

    介绍 使用范围较广的富文本编辑器.官方文档 config.js的常用配置 参考:https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_conf ...

  3. Java集合框架学习(十五) ListIterator接口详解

    ListIterator介绍 一个为list对象设计的迭代器,允许开发人员在2个方向上迭代,修改和获得list迭代位置. ListIterator 没有所谓当前元素. 它的游标位置总是位于previo ...

  4. 【Azure 环境】IntelliJ IDEA Community Edition 2021.2.3登陆Azure账号时,无法切换到中国区

    问题描述 在IntelliJ IDEA Community Edition 2021.2.3中开发Azure Function程序,最后准备部署到中国区 Azure Function中.如下,在Int ...

  5. 【Azure Developer】如何通过Azure REST API 获取到虚拟机(VM)所使用的公共IP地址信息

    问题描述 如何通过Azure REST API 获取到虚拟机(VM)所使用的公共IP地址信息 问题解答 由于直接获取到的虚拟机信息(Virtual Machines - Get)中,并不会包含虚拟机的 ...

  6. gopkg.in/go-playground/validator中比较有用的标签

    -  忽略|  或omitempty 有则验证,空值则不验证dive  潜入到切片.数组.映射中,例如 NumList []int `validate:"len=2,dive,gt=18&q ...

  7. 基于 Nebula Graph 构建图学习能力

    本文首发于 Nebula Graph Community 公众号 经常看技术文章的小伙伴可能会留意到除了正在阅读的那篇文章,在文章页面的正文下方或者右侧区域会有若干同主题.同作者的文章等你阅读:经常逛 ...

  8. 浅析图数据库 Nebula Graph 数据导入工具——Spark Writer

    从 Hadoop 说起 近年来随着大数据的兴起,分布式计算引擎层出不穷.Hadoop 是 Apache 开源组织的一个分布式计算开源框架,在很多大型网站上都已经得到了应用.Hadoop 的设计核心思想 ...

  9. 协程的async使用

    async与launch一样都是开启一个协程,但是async会返回一个Deferred对象,该Deferred也是一个job async函数类似于 launch函数.它启动了一个单独的协程,这是一个轻 ...

  10. 【转载】大数据OLAP系统--开源组件方案对比

    开源大数据OLAP组件,可以分为MOLAP和ROLAP两类.ROLAP中又可细分为MPP数据库和SQL引擎两类.对于SQL引擎又可以再细分为基于MPP架构的SQL引擎和基于通用计算框架的SQL引擎: ...