08|重试幂等:让程序 Exactly-once 很难吗?
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
分布式系统中的Exactly-once问题一直是一个难题。本文深入讨论了为什么不能保证Exactly-once、如何保证Exactly-once以及Exactly-once的挑战。在分布式系统中,网络故障和远端服务故障是导致消息传递无法保证Exactly-once的主要原因。为了解决这一问题,文章介绍了三种主要的实现方式:至少一次消息传递加消息幂等性、分布式快照加状态回滚以及整体重做。其中,至少一次消息传递加消息幂等性是最适用于在线业务架构系统的方式。然而,这种方式也面临着一些挑战。文章深入浅出地解释了这些挑战,为读者提供了全面的了解。通过本文的阐述,读者可以对分布式系统中的Exactly-once问题有一个清晰的认识,为解决类似问题提供了有益的参考。文章还讨论了分布式系统场景下的重试和幂等的相关问题,总结了保证Exactly-once的三种方式以及在分布式系统中确保Exactly-once面临的挑战。整体而言,本文为读者提供了深入的技术讨论,帮助他们更好地理解和解决分布式系统中的Exactly-once问题。
《深入浅出分布式技术原理》,新⼈⾸单¥59
全部留言(11)
- 最新
- 精选
- 松鼠鱼思考题:在 IM 系统中,我们如何实现幂等的消息发送接口? 以Kafka为例,生产者发送消息的时候会带上 ProducerId 和 SequenceNumber,相同批次(batch)的消息 SequenceNumber 是一样的,重复发送时不会被 broker 接受。 同时,开启幂等会默认 acks = -1,也就是一批消息被成功写入需要分区的所有同步副本都接收到才算数,以此确保不丢消息。在这个基础上加上幂等,二者共同保证精确一次。 以上虽然只能确保单次会话、单分区的幂等,但一般情况下,业务上我们会确保某一种类的消息固定发往某一分区(比如根据某个 key 值做哈希取余),而且在消费者端也可以做去重检查,因此问题不大。 如果需要全局的、跨越会话的幂等(精确一次),还是要开事务。
作者回复: 非常赞!
2022-02-1410 - Geek2014老师你好,想咨询一下 内部的2pc机制怎么实现额,感觉有点语焉不详额 然后我们在当前请求的内部通过 2PC 的机制,确保该请求的内部状态修改逻辑
作者回复: 在课程事务(二)的原子性中有详细的介绍。
2022-03-233 - 处女座♍️现在手里的项目正好是基于netty实现的IM即时消息项目,消息头中存了消息id(基于会话层面的递增id),客户端进入会话后会在分布式缓存中建立会话快照(session),session中会存放接收到的最大id,当服务端接收到消息后会比较当前id和session中的id,如果小于等于视为重复消息丢弃。当然这是个客服系统,可以容忍出现细微误差
作者回复: 赞,最好的系统设计都是贴合业务特点的。
2022-03-173 - Geek_192757请问老师,外部系统2PC方式具体要怎么做?
作者回复: 2pc 是保证多个操作的原子性的,用来确保在通过去重保证接口幂等的时候,去重和其他的操作整体是一个原子操作。这里以 IM 的发送消息接口为例介绍,IM 对发送消息接口支持 2PC 协议需要提供下面 3 个接口: Prepare 接口:用来确定当前的消息是否可以发送,如果可以发送,写好 undo 和redo 日志等操作 commit 接口:真正发送消息的操作 rollback 接口:回滚消息的操作 然后由 2PC 的协调者整体来执行协调工作。 在后面的课程“事务(二):原子性,对应用层提供的完美抽象”会有更详细的解释。
2022-02-1523 - lz404如果使用另外的存储比方说redis记录幂等,是不是二者之间就很难一致,可能出现没重试或者多重试
作者回复: 是的,可以通过 2PC 来保证 redis记录幂的操作和其他的操作是原子的。 不过很多业务场景下,是能容易小概率的不一致的,那么就可以直接通过 redis 记录就行。 我们在做架构设计的时候,一定要对架构设计的边界或者问题有清晰的认识,然后在基于业务情况做 trade-off 。
2022-02-171 - 李二木前端每次请求会在Header中带一个时间戳。有些接口要求幂等(可以理解为防止重复提交)。每次请求,都会把时间戳作为一个唯一标识来验证接口是不是重复提交。这样的方案可行吗?
作者回复: 思路是对的,不过时间戳是可能会重复的,不能做唯一标识。
2022-02-1431 - blentle老师能否提供类似的案例补充说明一下
作者回复: 你好,blentle,是怎么样的形式呢?
2022-02-16 - peter请教老师四个问题: Q1:怎么标记请求已经处理完成? Q2:“写处理结果”和“写入数据库”,是两个不同的操作吗? Q3:全局唯一ID一般怎么产生? Q4:关于重试幂等,能否举一两个具体的例子?互联网实践的例子。
作者回复: Q1:“标记请求已经处理”,可以直接在数据库中记录已经处理的请求ID,有新的请求来的时候,先查一下数据库,如果ID存在,则说明已经处理完成。 Q2:如果处理结果都是写入数据库的,就是一个操作 Q3:可以通过分布式ID生成器,或者使用uuid也可以 Q4:课程中的提到的支付场景中,就会经常使用。另外,有的时候,我们的系统和在调用第三方服务后,如果第三方服务是通过异步回调来给我们结果的,那么第三方服务一般都是最少一次的方式来回调,我们来通过幂等来保证正确性。
2022-02-142 - javaadu如果能有一些常见中间件的应用案例列举会更好2022-06-181
- Jack_1024有没有GitHub具体事例代码呀?大佬2022-04-241