Rabbit三两事

Rabbit三两事

一. RabbitMQ 简介

1. RabbitMQ有哪些作用呢?

消息系统允许软件、应用相互连接和扩展.这些应用可以相互链接起来组成一个更大的应用,或者将用户设备和数据进行连接.消息系统通过将消息的发送和接收分离来实现应用程序的异步和解偶.

或许你正在考虑进行数据投递,非阻塞操作或推送通知。或许你想要实现发布/订阅,异步处理,或者工作队列。所有这些都可以通过消息系统实现。

RabbitMQ是一个消息代理 - 一个消息系统的媒介。它可以为你的应用提供一个通用的消息发送和接收平台,并且保证消息在传输过程中的安全。

2. RabbitMQ有哪些特点呢?
2.1 可靠性

RabbitMQ提供了多种技术可以让你在性能和可靠性之间进行权衡。这些技术包括持久性机制、投递确认、发布者证实和高可用性机制。

2.2 灵活的路由

消息在到达队列前是通过交换机进行路由的。RabbitMQ为典型的路由逻辑提供了多种内置交换机类型。如果你有更复杂的路由需求,可以将这些交换机组合起来使用,你甚至可以实现自己的交换机类型,并且当做RabbitMQ的插件来使用。

2.2.1 交换机种类
direct,fanout,topic,header(非路由键匹配,功能和direct类似,很少用)。
前三种类似集合对应关系那样,(direct)1:1,(fanout)1:N,(topic)N:1
2.2.2 交换机与路由的三两事
1. fanout
fanout类型的Exchange路由规则它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中(无需路由)1:N 类型。
2. direct
direct类型的Exchange路由规则它会把消息路由到那些binding key与routing key完全匹配的Queue中(需要指定的路由才能完全匹配相对应的队列)1:1 类型。
3. topic
topic类型的Exchange路由规则它会把消息路由进行反向查询类似于模糊查询
1. 一般 routing key 的形式都是 “.” 分隔,用例:A1.B2.C3
2. Exchange路由规则使用topic类型可以使用 * || # 作为模糊查询的未知条件,* 用于匹配一个单词 # 用于匹配多个单词。
3. 举例:
3.1 前提:
A1.B2.C3 Queue1 队列1,A2.B2.C2 Queue2 队列2,A3.B3.C3 Queue3 队列3
存在以上三个队列。
3.2 结果:
根据 *.B2.* 的查询所需发送的队列为Queue1与Queue2
根据 A1.*.* 的查询所需发送的队列为Queue1与Queue3
根据 #.B2.# 的查询所需发送的队列为Queue1与Queue2
根据 #.B3.C3 的查询所需发送的队列为Queue3
4. headers
headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。

在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的键值对;如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue。

2.3 集群

在相同局域网中的多个RabbitMQ服务器可以聚合在一起,作为一个独立的逻辑代理来使用。

2.4 联合

对于服务器来说,它比集群需要更多的松散和非可靠链接。为此RabbitMQ提供了联合模型。

2.5 高可用的队列

在同一个集群里,队列可以被镜像到多个机器中,以确保当其中某些硬件出现故障后,你的消息仍然安全。

2.6 多协议

RabbitMQ 支持多种消息协议的消息传递。

2.7 广泛的客户端

只要是你能想到的编程语言几乎都有与其相适配的RabbitMQ客户端。

2.8 可视化管理工具

RabbitMQ附带了一个易于使用的可视化管理工具,它可以帮助你监控消息代理的每一个环节。

2.9 追踪

如果你的消息系统有异常行为,RabbitMQ还提供了追踪的支持,让你能够发现问题所在。

2.10 插件系统

RabbitMQ附带了各种各样的插件来对自己进行扩展。你甚至也可以写自己的插件来使用。

引用 RabbitMQ中文文档

二. 结合信道、交换器和路由键到队列

1、信道才是rabbit通信本质,生产者和消费者都是通过信道完成消息生产消费的。
2、交换器本质是一张路由查询表(名称和队列id,类似于hash表),这是一个虚拟出来的东西,并不存在真实的交换器。
3、消息的生命周期:生产者生产消息A 交由信道,信道通过消息(消息由载体和标签)的标签(路由键)放到交换器发送到队列上(其实就是查询匹配,一旦匹配到了规则,信道就直接和队列产生连接,然后将消息发送过去)
4、Channel是我们与RabbitMQ打交道的最重要的一个接口,我们大部分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等。

三. 安装RabbitMQ

3.1.1 windows安装:
  • 安装Erlang,下载地址 点击
  • 安装RabbitMQ,下载地址 点击
  • 在地址栏输入cmd并回车启动命令行,然后输入以下命令启动管理功能。
rabbitmq-plugins enable rabbitmq_management
3.1.2 Linux安装:
  • 下载rabbitmq 3.7.15的Docker镜像;
docker pull rabbitmq:3.7.15
  • 使用Docker命令启动服务;
docker run -p 5672:5672 -p 15672:15672 --name rabbitmq \
-d rabbitmq:3.7.15
  • 进入容器并开启管理功能;
docker exec -it rabbitmq /bin/bash
rabbitmq-plugins enable rabbitmq_management
  • 开启防火墙便于外网访问(阿里or腾讯等服务器可在控制台设置白名单)。
firewall-cmd --zone=public --add-port=15672/tcp --permanent
firewall-cmd --zone=public --add-port=5672/tcp --permanent
firewall-cmd --reload
3.1.3 Debian / Ubuntu安装:

四. RabbitMQ解决积压问题

在日常工作中使用RabbitMQ偶尔会遇不可预料的情况导致的消息积压,一般出现消息积压基本上分为几种情况:
  1. 消费者消费消息的速度赶不上生产速度,这总问题主要是业务逻辑没设计好消费者和生产者之间的平衡,需要改业务流程或逻辑已保证消费度跟上生产消息的速度,譬如增加消费者的数量等。

  2. 消费者出现异常,导致一直无法接收新的消息,这种问题需要排查消费的逻辑是不是有问题,需要优化程序。

解决思路:
  • 拆分MQ,生产者一个MQ,消费者一个MQ,写一个程序监听生产者的MQ模拟消费速度(譬如线程休眠),然后发送到消费者的MQ,如果消息积压则只需要处理生产者的MQ的积压消息,不影响消费者MQ。
  • 拆分MQ,生产者一个MQ,消费者一个MQ,写一个程序监听生产者的MQ,定义一个全局静态变量记录上一次消费的时间,如果上一次时间和当前时间只差小于消费者的处理时间,则发送到一个延迟队列(可以使用死信队列实现)发送到消费者的MQ,如果消息积压则只需要处理生产者的MQ的积压消息,不影响消费者MQ。
  • 使用Redis的List或ZSET做接收消息缓存,写一个程序按照消费者处理时间定时从Redis取消息发送到MQ。
  • 设置消息过期时间,过期后转入死信队列,写一个程序处理死信消息(重新如队列或者即使处理或记录到数据库延后处理)。
其中使用延时队列会相对来说逻辑简单,业务逻辑变更也不大,在RabbitMQ中,可使用死信来及延时队列插件rabbitmq_delayed_message_exchange两种方式实现延时队列。使用插件可以在官网找到:https://www.rabbitmq.com/community-plugins.html

猜你喜欢

转载自blog.csdn.net/weixin_43869435/article/details/118209030