94 | 项目实战二:设计实现一个通用的接口幂等框架(设计)
该思维导图由 AI 生成,仅供参考
幂等处理正常流程
- 深入了解
- 翻译
- 解释
- 总结
设计一个通用的接口幂等框架是一项复杂的任务,需要考虑各种异常情况的处理。在正常流程中,幂等框架需要在接口请求的三个阶段中添加幂等相关的逻辑。对于异常情况的处理,需要区分业务异常和系统异常,并根据不同类型的异常来决定是否允许重新执行业务逻辑。此外,还需要考虑业务系统宕机的情况,以及如何处理幂等框架本身的异常。在处理业务系统宕机时,可以考虑将幂等号存储到业务数据库中,并同步给幂等框架的Redis数据库,以保证数据一致性。对于幂等框架的异常处理,需要保证接口请求失败,以避免重复执行业务逻辑导致错误。综合来看,设计一个高度容错的幂等框架需要考虑各种异常情况,并在实际工程中根据具体情况做出灵活的处理。 在正常情况下,幂等框架的处理流程是比较简单的,调用方生成幂等号,传递给实现方,实现方记录幂等号或者用幂等号判重。但是,幂等框架要处理的异常情况很多,这也是设计的复杂之处和难点之处。 针对三种不同类型的异常,讲解了幂等框架的应对思路。 对于业务代码异常,为了让幂等框架尽可能的灵活,低侵入业务逻辑,发生异常(不管是业务异常还是系统异常),是否允许再重试执行业务逻辑,交给开发这块业务的工程师来决定。 对于业务系统宕机,建议业务系统记录SQL的执行日志,在日志中附加上幂等号,以便在机器宕机时根据日志来判断业务执行情况和幂等号的记录是否一致。 对于幂等框架异常,选择让接口请求失败,相应的业务逻辑就不会被重复执行了,业务就不会出错。 虽然幂等框架要处理的异常很多,但考虑到开发成本以及简单易用性,对某些异常的处理在工程上做了妥协,交由业务系统或者人工介入处理。这样就大大简化了幂等框架开发的复杂度和难度。 异常情况考虑是否全面,处理是否得当,很能体现一个程序员的逻辑思维能力、工程能力。除了我们今天讲到的异常,在幂等框架中,还能想到有哪些其他异常情况会发生?又该如何应对呢?
《设计模式之美》,新⼈⾸单¥98
全部留言(26)
- 最新
- 精选
- 有铭幂等框架是宁可错杀,不可放过,放过了(多执行)修复难度太大,错杀了无非是再执行一次
作者回复: 是的,跟限流正好相反!
2020-06-08271 - qwerboo那如果事务回滚,同步到redis中的值怎么处理呢?不删除的话下次请求不就会被拒绝吗?
作者回复: 事务回滚的话 不会同步到redis的,只有事务完全执行完了,才会写redis
2020-07-2379 - 楊_宵夜争哥,文中关于[业务系统宕机处理]那节的第二段, " 如果幂等号已经记录下了,但是因为机器宕机,业务还来得及执行,按照刚刚的幂等框架的处理流程,即便机器重启,业务也不会再被触发执行了,这个时候该怎么办呢?除此之外,如果记录幂等号成功了,但是在捕获到系统异常之后,要删除幂等号之前,机器宕机了,这个时候又该怎么办? " 应该是业务还‘没‘来得及执行吧? 吹毛求疵般地执行文章评审,手动狗头。
作者回复: 嗯嗯 多谢指出,我改下
2020-06-2524 - KLOOOP"针对这个问题,我们还有另外一种解决方案。那就是,在存储业务数据的业务数据库( 比如 MySQL)中,建一张表来记录幂等号。幂等号先存储到业务数据库中,然后再同步给幂等框架的 Redis 数据库。"--- 1.记录幂等号;2.执行业务逻辑;3.同步给幂等框架的reidis;4.以上都成功,提交事务。这样理解对么?
作者回复: 只需要1+2在一个事务中就可以,这样就可以依赖数据库事务来解决,不需要分布式事务。
2020-06-2253 - Jeff业务写执行日志到DB,性能问题怎么解决?不如写本地日志,虽然系统异常时日志可能丢失,但是不影响性能,最后只要选好日志框架问题不会太大
作者回复: 也可以的
2020-08-122 - Jxin1.这教的不止是设计模式。还包含了设计过程中的权衡取舍。看栏主的专栏,就像个小迷弟一样,每篇都是666打call。 2.针对今天的专栏延伸一个问题。我们知道rpc接口一般都是result返回的模式。然后系统的异常可以分为业务异常和技术异常,业务异常一般重试解决不了,需要主动告警人工介入,技术异常则往往需要重试,自动化解决。这就导致result中的code往往有多个值,用于区分业务异常和技术异常走相应的逻辑。 但是我觉得这很难受,我希望result的code只有0和1,仅用于表示是否发生了技术异常,甚至我希望没有result这种返回模式(rpc框架层面处理技术异常),毕竟rpc技术就是让开发者像调用本地接口一样调用远程接口。但是如果code只表示技术异常,那么属于业务异常的标记和异常消息就只能放在data中,这又让接口返回数据和业务异常耦合了。当然,我们也可以不捕捉业务异常,让它在调用侧抛出,这更贴合像调用本地方法一样调用远程方法的理念,但这样站在服务方的角度,最外层的接口都没有处理异常,又显得不合适了。 所以,请问栏主和各位同学,rpc接口的返回应该怎么设计合理,你们又是怎么实践的? 3.回答课后题。比如某个策略依赖配置表,由于配置信息缓存延迟,发生了业务异常。这时候异常是业务异常,但引起异常的原因是缓存延迟这个技术问题。重试可以走通流程,但需要人工介入刷新缓存,或则等待缓存刷新。2020-06-081123
- 饭一路跟着栏主,坚持到现在,一篇篇啃下来,不知不觉的,如今跟人聊起设计,突然也讲得头头是道。刷完这一波,再重读第二遍2020-06-1112
- tingye二八原则这里看起来也适用,20%正常处理代码,80%异常处理代码。 业务异常可能有更复杂的情况,比如第一次业务操作失败原因可能是依赖的业务条件未达成(B用户不存在),但延迟一段时间就满足了(B用户创建好了),这种可能需要支持延迟重试策略,而重试也要给个上限,避免死循环2020-06-0911
- Geek_35cfdd那这个幂等框架每次都要依赖开启数据库事务,不然无法保障业务数据和幂等框架插入的数据同时成功或者同时失败。而开事务本身是业务方根据自己的业务场景决定,如果业务本身不需要开事务,而引入幂等框架需要强开事务,这种耦合性本身也是比较高的。 我的想法是,可以在幂等框架中幂等键引入中间状态。成功状态。失败状态。三种。 在 中间状态和成功状态 都可以幂等住。 失败状态(对应文中的删除)。 文中说的极端情况,可以引入异步任务,去更新。2020-10-1416
- Jian每天下班回家看一讲,快尾声了2020-06-093