个人专题目录
怎么保证rabbitmq不丢消息(消息可靠性保障)
提出需求:如何能够保证消息的 100% 发送成功?
首先大家要明确任何一个系统都不能保证消息的 100% 投递成功,我们是可以保证消息以最高最可靠的发送给目标方。
在RabbitMQ中采用 消息补充机制 来保证消息的可靠性
步骤分析:
参与部分:消息生产者、消息消费者、数据库、三个队列(Q1、Q2、Q3)、交换机、回调检查服务、定时检查服务
- 消息的生产者将业务数据存到数据库中
- 发送消息给 队列Q1
- 消息的生产者等待一定的时间后,在发送一个延迟消息给队列 Q3
- 消息的消费方监听 Q1 队列消息,成功接收后
- 消息的消费方会 发送 一条确认消息给 队列Q2
- 回调检查服务监听 队列Q2 发送的确认消息
- 回调检查服务接收到确认消息后,将消息写入到 消息的数据库表中
- 回调检查服务同时也会监听 队列Q3延迟消息, 如果接收到消息会和数据库比对消息的唯一标识
- 如果发现没有接收到确认消息,那么回调检查服务就会远程调用 消息生产者,重新发送消息
- 重新执行 2-7 步骤,保证消息的可靠性传输
- 如果发送消息和延迟消息都出现异常,定时检查服务会监控 消息库中的消息数据,如果发现不一致的消息然后远程调用消息的生产者重新发送消息。
以车联网数据种类进行简单归类如下:
- 终端上行的数据:
- 主流数据,量多、又频繁。(位置数据,OBD数据),能丢
- 特别预制条件下,满足,量少,比如报警,连续报警同一个警,平台要去重,不能丢
- 司机发起的请求,量小,不能丢
- 司机的应答,(平台侧发起),不能丢
- 下行到终端数据:
- 设置类不能丢
- 通知类,一段时间以后 可以丢。 开会等
- 查询类 最好不要丢
- 系统内配置消息,量小,一定时间内不能丢,时间过,重发该消息,消费者 要能去重。
1. 从rabbitmq自身支持的层面
exchange、queue、messages需要持久化。
consumer 收到后,手动送出ACK,即:producer---------------broker---------------ACK------------------consumer
- publisher confirm方式(http://www.rabbitmq.com/confirms.html)
保证传输过程中不丢,需要两处确认,producer----CONFIRM----broker-----ACK---consumer
保证在producer、broker、consumer 中不丢,这里只考虑 broker崩溃或重启,需要exchange、queue、messages都要持久化
broker的messages持久化 完成后,才会 CONFIRM 给produer
consumer的处理完成后,才会ACK给broker
- queue 镜像方式(http://www.rabbitmq.com/ha.html)
- 这种方式可以 不使用 messages的持久化,其他跟方法2 相似,exchange、queue是否持久都可以。
2. 从应用层面支持
如果某个业务组件,在一定时间内会重复 发送该消息,是由于没有收到相应的应答,重复发送的次数是有限的,多次后,需要人工排查。
3. 从平台的操作层面支持
操作员可以重复该失败或无响应的操作
当负载增大时, RabbitMq如何扩容
1. 构建mq的集群:
(具体参考http://www.rabbitmq.com/clustering.html)
构建本地集群,提高broker的吞吐量。在此本地集群基础上可以配置 queue 镜像从而带来 queue HA。
本地集群可以通过 federation 插件 进行WAN互联, WAN集群可以平衡 多个本地集群之间负载。
本地集群的扩展,保证足够disk nodes 基础上,只要增加ram nodes 。
2. producer和consumer的 自由扩展
(具体参考http://spring.io/blog/2011/04/01/routing-topologies-for-performance-and-scalability-with-rabbitmq/)
3. 提升RabbitMQ性能——开启erlang HiPE特性。
4. rabbitmq 的 flow control ,在一个 connection里面,要么使用多channel生产,要么使用多channel消费, 最好不要生产channel和消费 channel共存于一个connection内
(具体请参考http://previous.rabbitmq.com/v2_8_x/memory.html)。
消息幂等性处理
幂等性指一次和多次请求某一个资源,对于资源本身应该具有同样的结果。也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同。
在MQ中指,消费多条相同的消息,得到与消费该消息一次相同的结果。
在本教程中使用 乐观锁机制 保证消息的幂等操作