昨天跟小伙伴们分享了如何在 RabbitMQ 中确保消息发送可靠性的问题(我是如何在微人事项目中提高RabbitMQ消息可靠性的?),我们主要是两个思路:
- 开启消息发送失败回调,路由失败回调
- 开启定时任务巡查,发现有发送失败的消息自动重新投递
双管齐下,我们确保了消息发送的可靠性。
但是,在这样的机制下,又带来了新的问题,就是消息可能会重复投递,进而导致,消息重复消费,例如一个员工入职了,结果收到了两封入职欢迎邮件,这是不对的,所以,今天松哥又给大家带来了一个新的视频,聊一聊如何确保一条消息只消费一次。
说到这个话题,我们就不得不先来说说消息幂等性。
53.1 简单说说幂等性
幂等性本身是数学上的概念,即使公式:f(x)=f(f(x)) 能够成立的数学性质。在开发领域,则表示对于同一个系统,使用相同的条件,一次请求和多次请求对系统资源的影响是一致的。
在分布式系统中幂等性尤为重要,因为分布式系统中,我们经常会用到接口调用失败进而进行重试这个功能,这样就带来了对一个接口可能会使用相同的条件进行重复调用,在这样的条件下,保证接口的幂等性就尤为重要了。
了解了问题,那么解决方案就很好整了,常见的方案有:
- MVCC
- Token 机制
- 设计去重表
- …
MVCC 是多版本并发控制,这种方式就是在数据更新的时候需要去比较所持有的数据版本号,版本号不一致的话,操作会失败,这样每个 version 就只有一次执行成功的机会,一旦失败了必须重新获取。这种方式松哥以后可以抽空和大家细聊。
Token 则是目前使用比较广的一种方式,核心思想就是每个操作都有一个唯一凭证 token,一旦执行成功,对于重复的请求,总是返回同一个结果。
53.2 微人事解决方案
松哥这次在微人事的 RabbitMQ 消费端实际上就是采用了 Token 这种方式。
大致的思路是这样,首先将 RabbitMQ 的消息自动确认机制改为手动确认,然后每当有一条消息消费成功了,就把该消息的唯一 ID 记录在 Redis 上,然后每次收到消息时,都先去 Redis 上查看是否有该消息的 ID,如果有,表示该消息已经消费过了,不再处理,否则再去处理。
那么具体是怎么实现的呢,请看大屏幕:
【视频地址】
好了,通过昨天和今天一共三个视频,松哥主要和大家分享了微人事中是如何解决 RabbitMQ 消息可靠性的,如果小伙伴们没看昨天的视频,不妨去瞅一瞅:我是如何在微人事项目中提高RabbitMQ消息可靠性的?
当然,如果小伙伴们对完整的微人事项目视频感兴趣,可以看看这篇文章【微人事视频教程】。
本文视频中涉及到的所有代码包括数据库脚本,都已经提交到 GitHub 和 Gitee 上了,地址分别是:https://github.com/lenve/vhr 和 https://gitee.com/lenve/vhr ,小伙伴们可以下载参考。
扫码关注微信公众号 江南一点雨,回复 2TB,获取超 2TB Java 学习教程~