加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

可重入锁思想,设计MQ迁移方案

06/19 11:10
762
阅读需 8 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

作者:小傅哥,博客:https://bugstack.cn

大家好,我是技术UP主小傅哥。

如果你的MQ消息要从Kafka切换到RocketMQ且不停机,怎么做?在让这个MQ消息调用第三方发奖接口,但无幂等字段又怎么处理?今天小傅哥就给大家分享一个关于MQ消息在这样的场景中的处理手段。

这是一种比较特例的场景,需要保证切换的MQ消息不被两端同时消费,并且还需要在一段消费失败后的MQ还可以继续重试。并且这一端消费的MQ消息,也要保证自身的幂等。

我们知道一般通用场景下,MQ消息都会有一个业务唯一ID值,用于接收方做仿重处理。但除此之外还应该有一个MQ消息本身的ID,这个ID也要全局唯一,每一条消息都要有一个ID,这是因为MQ是可能重复发送的(发送MQ成功,但获取MQ发送结果响应超时或更新库表消息状态失败,则重复发送),如果没有消息的唯一ID也就没法确保是哪一条消息了。

这个ID可以用于;唯一标识、去重、链路追踪、幂等性、事务以及安装性等,但可能有些伙伴在做MQ消息发送的时候,是容易忽略而没有在MQ中添加这个ID,或者随意用时间戳来当ID用,这样都是不合理的。会影响一些场景的代码健壮性设计。

需求背景描述好了,接下来,我们看看这样的场景怎么设计。

1. 场景问题

将原本使用 Kafka 的MQ方式,迁移到 RocketMQ,同时部分场景的 MQ 消息调用三方接口是没有幂等字段的,需要做好程序兼容处理。

2. 场景思考

首先我们要知道在分布式架构下,我们每做的技术方案都要考虑顺序性和临界状态。像是MQ的生产和消费都是多套应用实例部署的,那么生产端发送出来的MQ消息到不同的队列中也是有延迟和存放顺序以及拉取消费不同的情况。如;生产端发送MQ为A、B、C、D,但到Kafka/RocketMQ以及不同的消费端拉取时,不一定是A、B、C、D的顺序,那么直接做切量开关,是可能导致一个A消息在Kafka队列中消费完,点击切换开关(一种切量哈希计算手段,如消息{A}哈希值最后两位当做百分比用),正好RocketMQ也会把A消费掉。这样同一个消息就被重复消费了。

3. 方案设计

在整个方案设计中,我们要考虑几个非常重要的点。如图;

    1. 一个是切换的两端MQ消费是抢占式加锁,避免重复消费。这是因为切量开关,切换过程中,两个消息队列中的MQ并不是顺序可靠的,可能存在重复消费,所以要加分布式锁。一段MQ消费失败要进行重试,但这个时候不能在消费失败后删分布式锁,因为MQ消费都是很快的,可能导致删锁后另外一端MQ进行了相同的消费。那可能有些伙伴会说,那也没关系呀,反正失败的这段没有消费成功。当往往失败并不一定是直接的结果失败,可能是网络失败,可能是超时失败等。也就是实际成功了,但超时反馈了。所以不能被其他端重复消费,并且要保证自己这一端消费失败后可重试。所以这块要设计可重入锁,也就是 setnx 加锁的值,为自身一段的 mq 类型,这样自己在接收mq消息以后,检查锁为自身加锁值可重试。这样也就保证了一端消费重试,不会让另外一端把MQ也跟着消费掉,因为setnx存在,并且有加锁值判断,所以不能进入。另外MQ消息还可能存在同一个MQ发送多次的场景,这个是非常正常的。比如,你再发送MQ的时候,超时网络抖动失败(1万次会有1次),那么就会补偿重发。但这个MQ已经发送过了,所以会接收2条MQ消息。那么在消费的时候,不能让2个MQ消息都进入消费中,因为多台实例消费,可能都去调用发奖了。那么这里还需要给MQ的ID进行幂等加锁。确保一个MQ消息,失败后,顺序轮训重试。也就保证了,发奖的过程中不会出现超发奖品。

大部分三方接口还是有幂等字段的,有的话会更好。

      1. 另外还有2个开关,一个是

    消费开关

      1. ,一个是

    切量开关

      。消费开关要在整个新的MQ改造工程工程全部上线后开启,但还要被切量开关限定消费。开启后,切量开关才会生效。切量是一种哈希值的百分比比对,比如一个哈希值最后两位是10,那么切量配置小于等于10%则这个MQ则可以被切量后消费,另外一段则不消费这个MQ。另外,为了方便测试线上功能,还会加入白名单。不过大部分时候这类东西会用通用组件能力解决。

这样的场景方案设计,是非常值得积累的,同类的思想也可以帮我们解决很多共性问题。

4. 加入学习

注意,像这样的场景方案,在【星球:码农会锁】实战项目中有非常多的运用。还包括:大营销、OpenAI 应用、API网关、Lottery抽奖、IM通信、SpringBoot Starter 组件开发、IDEA Plugin 插件开发、支付SDK、动态线程组件、透视业务监控等,并还有开源项目学习。

如果大家希望通过做有价值的编程项目,提高自己的编程思维和编码能力,可以加入小傅哥的【星球:码农会锁】。加入后解锁所有往期项目,还可以学习后续新开发的项目。

这样成体系的全量项目学习,放在一些平台售卖,至少都要上千块。但小傅哥的星球,只需要100多,就可以获得大厂架构师对你手把手教学!

星球全程手把手指导教学,遇到技术问题帮忙排查代码。已经有很多伙伴开始学起来了,还有大家交的作业笔记。有了的项目驱动学习,清晰的目标感,大家冲起来也有了更明确的方向!干干干!!!

在今年的面试中,星球帮助众多伙伴拿到微信支付京东科技度小满蚂蚁金服Lazada(电商优惠营销)快手美团到店等Offer,还有的校招生薪资最高年包到45w!

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
CSTCV16M0X51Q-R0 1 Murata Manufacturing Co Ltd Ceramic Resonator, 16MHz Nom, CERAMIC PACKAGE-3
$0.62 查看
FTLF1319F1HTL 1 Finisar Corporation Transceiver, 1270nm Min, 1355nm Max, 2125Mbps(Tx), 2125Mbps(Rx), LC Connector, Through Hole Mount
$129.68 查看
ACPL-333J-500E 1 Broadcom Limited Optoelectronic Device, ROHS COMPLIANT, SURFACE MOUNT, SOP-16
$7.35 查看

相关推荐

电子产业图谱

作者小傅哥多年从事一线互联网Java开发,从19年开始编写工作和学习历程的技术汇总,旨在为大家提供一个较清晰详细的核心技能学习文档。如果本文能为您提供帮助,请给予支持(关注、点赞、分享)!