润典RabbitMQ使用规范手册v1.0
使用规范
RabbitMQ 是一个非常流行的开源消息中间件,用于在分布式系统中传递消息。为了确保RabbitMQ能够高效、可靠地工作,我们需要遵循一定的使用规范,以便我们更好的使用RabbitMQ。
命名规范
Exchange: 模块名.功能名,例如 order.payment。
Queue: word.word,例如 order.queue。
Routing Key: word.word,例如 payment.request。
注意:. 之间的部分被视为一个单词,这有助于使用通配符 * 和 # 进行匹配。
角色权限
普通用户:可以登录管理控制台,操作exchange、queue,但不能管理策略。
策略制定者 (policymaker):除了上述权限外,还可以管理策略。
虚拟主机 (Virtual Host)
隔离性:每个虚拟主机相当于一个独立的消息服务器,彼此之间是隔离的。
推荐使用场景:不相关的业务采用虚拟主机进行隔离。
消息持久化
设置队列和消息的持久化属性,防止 RabbitMQ 重启后消息丢失。
使用 durable 参数设置队列持久化,使用 persistent 参数设置消息持久化。
使用模式
Fanout:广播模式,将消息发送给所有绑定的队列。
Direct:路由模式,根据routing key将消息发送到指定的队列。
Topic:主题模式,使用通配符来匹配routing key。
Headers:基于消息头的路由模式。
合理规划交换机和队列
根据业务需求设计交换机(Exchange)和队列(Queue),避免过多或过少的交换机和队列。
使用合适的交换机类型(如 Direct、Topic、Fanout、Headers)。
合理设置消息 TTL
对不需要长期保存的消息设置 TTL(Time-To-Live),防止队列中堆积过多无用消息。
使用死信队列
配置死信队列(DLX),处理消息消费失败或过期的情况,防止消息丢失。
限流
使用 basic.qos 方法设置消费者的限流,防止消费者处理不过来导致消息堆积。
监控和报警
配置 RabbitMQ 的监控工具(如 Prometheus、Grafana),监控 RabbitMQ 的性能指标(如:进程数、内存使用情况、磁盘使用情况、队列长度、消息堆积、消费者状态等)。
设置报警机制,及时发现和处理异常情况。
合理配置连接池
在客户端使用连接池,减少连接建立和关闭的开销。
合理配置连接池的大小,避免连接过多导致资源耗尽。
安全性
配置 RabbitMQ 的访问控制,使用用户名和密码进行身份验证。
配置防火墙规则,限制 RabbitMQ 的访问来源。
定期清理
定期清理不再使用的交换机、队列和绑定关系,保持 RabbitMQ 的整洁和高效。
控制消息体大小
考虑到自建服务和云PaaS的兼容性,我们建议将报文存放在Redis中,将缓存的Key作为RabbitMQ的消息进行发送,以控制报文的体积,避免过大的保存发送到消息队列中。
常见问题及解决方案
连接问题
问题描述:无法连接到 RabbitMQ 服务器。
解决方案:
- 确保 RabbitMQ 服务器正在运行。
- 检查防火墙设置,确保端口(默认 5672)开放。
- 确认客户端配置的主机名、端口、用户名和密码正确。
消息积压
问题描述:队列中的消息积压,处理速度跟不上生产速度。
解决方案:
- 增加消费者数量,提高消息处理能力。
- 优化消费者代码,减少处理时间。
- 使用消息优先级,确保重要消息优先处理。
内存使用过高
问题描述:RabbitMQ 内存使用过高,导致性能下降。
解决方案:
- 配置合理的内存限制,使用 vm_memory_high_watermark 参数。
- 定期清理不必要的队列和消息。
- 使用磁盘存储(持久化)来减少内存占用。
磁盘空间不足
问题描述:磁盘空间不足,导致 RabbitMQ 无法正常工作。
解决方案:
- 配置合理的磁盘空间限制,使用 disk_free_limit 参数。
- 定期清理不必要的持久化消息和队列。
- 增加磁盘空间或使用外部存储。
消息丢失
问题描述:消息在传输过程中丢失。
解决方案:
- 使用持久化消息(persistent)。
- 确保队列和交换器持久化。
- 使用事务或确认机制(ack)确保消息成功处理。
网络分区
问题描述:网络分区导致 RabbitMQ 集群节点之间通信中断。
解决方案:
- 配置合理的网络分区策略(如 pause_minority)。
- 确保网络稳定,减少分区发生的可能性。
- 使用镜像队列,确保消息在多个节点上都有副本。
权限问题
问题描述:用户权限不足,无法执行某些操作。
解决方案:
- 检查并配置正确的用户权限。
- 使用 RabbitMQ 管理控制台或命令行工具设置用户权限。
高可用性
问题描述:RabbitMQ 单点故障,导致服务不可用。
解决方案:
- 使用 RabbitMQ 集群,提高可用性,如自建请使用RabbitMQ 3.8以后新增的仲裁队列集群。
- 配置镜像队列,确保消息在多个节点上都有副本。
- 使用负载均衡器,分发请求到不同的 RabbitMQ 节点。
消息顺序消费
问题描述:在某些应用场景中,需要确保消息按照特定的顺序被消费。
解决方案:
- 单一队列顺序消费:将所有需要按顺序处理的消息发送到同一个队列中,并使用一个消费者单线程去处理消费队列中的消息。
- 设置消息序号标识:根据队列中消息的顺序设置一个递增的序号,当消费者消费处理时判断当前消息的序号的前一位是否已存在消息的处理记录表中,不存在说明前面一个消息还未处理完,然后不断轮询记录表中的前一个序号的记录,直到查询到前一个序号的记录之后再执行当前消息的处理逻辑,执行完成后再将当前消息的序号信息存储到记录表中。