一、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. Js中的逻辑运算符

    Js中的逻辑运算符 JavaScript中有三个逻辑运算符,&&与.||或.!非,虽然他们被称为逻辑运算符,但这些运算符却可以被应用于任意类型的值而不仅仅是布尔值,他们的结果也同样可以 ...

  2. Spring Boot学生信息管理系统项目实战-4.学生管理

    1.获取源码 源码是捐赠方式获取,详细请QQ联系我 :) 2.实现效果 2.1 导出导入模板 2.2 导入学生数据 3.项目源码 只挑重点讲,详细请看源码. 学生管理包含了学生信息的增删改查,这里我只 ...

  3. [攻防世界][Web]PHP2

    打开靶机对应的url 就一行字 Can you anthenticate to this website? 第一感觉就需要做目录文件扫描 使用御剑和dirsearch进行扫描,发现一个文件 index ...

  4. 记录级别索引:Hudi 针对大型数据集的超快索引

    介绍 索引是一个关键组件,有助于 Hudi 写入端快速更新和删除,并且它在提高查询执行方面也发挥着关键作用. Hudi提供了多种索引类型,包括全局变化的Bloom索引和Simple索引.利用HBase ...

  5. SSH不对称密钥自动登入服务器

    SSH不对称密钥自动登入服务器 1.先在自己的电脑上创建密钥对 ssh-keygen -t rsa Windows下生成SSH密钥 $ ssh-keygen -t rsa -C "youre ...

  6. React时间转换为具体的年月日上午下午

    export default class index extends Component { constructor() { super(); this.state = { date: new Dat ...

  7. 我的第一个项目(九) :飞机大战Vue版本塞到主页

    好家伙, 这是未进行分包的vue版本的飞机大战 效果如下:   这里说明一下,大概使用逻辑是提供一个<div> 然后在这<div>中渲染游戏 游戏主界面代码如下: 1 < ...

  8. 【Azure Redis 缓存】Azure Redis读写比较慢/卡的问题排查

    问题描述 在使用Azure Redis的过程中发现读写比较慢,非常卡,执行扩容6-->13GB后,过一段时间也满了.在通过门户Console连接到Reids,通过info Memory名称查看到 ...

  9. 关于STM32Fx部分引脚不可以正常输出高低电平的解决办法(不可以正常使用)

    一.概述 在一次电路版测试中,发现stm32的部分引脚不可以正常的输出高低电平,刚开始以为是板子没有焊接好所以导致的经过多次的测试,发现电路版没问题.当时就想不清楚了,后面就问学长,还有实验室的学长一 ...

  10. 九: Mysql逻辑架构

    # 逻辑架构 1. 服务器处理客户端请求 首先MySQL是典型的C/S架构,即Client/Server架构,服务器端程序使用的mysqld· 不论客户端进程和服务器进程是采用哪种方式进行通信,最后实 ...