RabbitMQ实现消息100%投递的详细设计和测试方案

目标

  • 实现一个在相对恶劣的条件下,依旧保证消息百分百投递或消费的消息队列。

存在的挑战及简易方案

  • 1.你说百分百投递,万一你mq挂了,怎么投递?
    使用镜像队列
  • 2.那要是网络不稳定,消息没有送到exchange或者没有送到queue怎么办?
    conform模式 和 return模式 配合消息重发的线程池重发消息
    • 2.1.消息发送至某一台mq,但是这台mq突然停电,来不及同步到其他镜像队列怎办?
      消息持久化至硬盘,消息重启恢复
    • 2.2.如果消息刚到内存,还没来及固化到硬盘,此时发生故障,导致消息丢失怎么办?
      这次消息是真的丢失了,但是有补偿机制
  • 3.消息执行(消费)失败,或者消费后消息没有发送至队列怎办?
    (1)发送消息时,除了发给消费端,还发给了补偿端做消息登记。 (2)消费端消费后,会把消息发送到补偿端进行同步。 (3)补偿机制会在间隔时间内重新发消息到补偿端,获取消息状态,要么重发,要么关闭。
  • 4.那万一生产端多发了消息,或者补偿机制多发了消息,怎么保证幂等消费?
    redis分布式锁:Redisson实现消息幂等
  • 5.大流量进入mq的时候,来不及消费怎么办?
    mq有削峰填谷的算法
  • 6.上述百分百投递保障和单节点相比,对性能影响有多大?
    测试方案: (1)镜像队列在不同宕机条件下的消息可达性测试 (2)单节点和百分百投递队列的性能对比测试。
  • 7.消息队列的类是交由spring管理的单例,如何保证在多处引用的时候,不会引起线程安全问题
    将scope改成request

实现架构图

在这里插入图片描述
图片来源:RabbitMQ保障消息 100% 投递成功方案

实现步骤

  • 消息送达后客户端后,先进行消息落库(数据库a),作为日后查验(消息补偿)的凭据
  • 消息同时传递至2条mq队列,一条用于缓存信息,后续进行消费(大流量下进行削峰填谷),另一条用于补偿机制获取消息,进行消息查询和重发的,落库至(数据库b)
  • 服务端消费后的消息回执发送到队列,补偿机制进行数据更新(数据库b)
  • 消费端的delay线程对刚才的消息进行query,补偿机制根据query次数决定是重发消息还是等待消息。

测试架构图

在这里插入图片描述

测试案例设计

  • 编写一个客户端程序,使用封装好的百分百投递的jar包来传递消息,对外暴露一个接口。
  • 使用jmeter发压,通过Nginx负载到两个客户端程序的接口上,分别测试一千条数据、一万条数据、十万条数据的完成时间和投递成功率。
  • consumer端使用一个接口来接受数据,并用线程sleep 5毫秒来模拟线程处理数据。
  • 等到consumer端不在处理数据后,查看数据库的消息落库情况和消息消费情况
  • 消费时间公式
    • 消费时间 = consumer端最后一条数据打印出来的时间 - 开始发压时间,
    • 这里可以测试 镜像队列、单节点、消息固化和非固化的投递效率。
  • 消息投递保障率
    • 查询数据库落库的数据 / 发压的数据,
    • 查询数据库完成消费的数据 / 发压的数据,
    • 两者取最小值,就是消息投递保障率。

未完待续

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值