- 幂等定义:可以安全地重试请求,而不会意外执行相同的操作两次
- 幂等解决的问题:各种超时重试、拦截重复请求,减少无效请求到下游服务
国外渠道幂等处理
Checkout:https://docs.checkout.com/payments/manage-payments/retry-a-payment
Adyen: https://docs.adyen.com/development-resources/api-idempotency#enable-idempotency
Stripe: https://stripe.com/docs/api/idempotent_requests#idempotent_requests
时序图

总体实现思路
- gateway 实现 或者在下游服务实现。gateway 实现幂等,这样下游服务可以不用处理幂等,在gateway 统一处理,下游服务处理,可以保证超时情况精确处理。即使采用切面方式,代码也有一些侵入性
- header 中增加idempotentKey 来判断是否幂等
- 各个业务线之间idempotentKey 相互隔离
- idempotentKey 并发请求,需要redis 分布式锁拦截 返回409
- 请求下游服务成功,保存报文到redis 设置超时时间,细节点:如果下游返回异常,仍保存
- idempotentKey 再次请求,从redis get response 及 status 响应调用方
- 细节:若果gateway 请求 下游服务 超时(connect、readTime)处理方式?渠道没有描述细节点处理方式
两种方式对比:
1. 不做幂等保存,业务可以方便重试,但是需要保证下游服务,非并发请求下的幂等校验,存在重复处理请求风险(可以按接口级别分类,如果是查询类型操作可以不用幂等)
2. 做幂等校验,可以解决重复下单。但是会影响api调用体验,业务方重试也无用处。只能换订单号或者换idempotentKey
stripe有一行描述:Results are only saved if an API endpoint started executing. If incoming parameters failed validation, or the request conflicted with another that was executing concurrently, no idempotent result is saved because no API endpoint began execution. It is safe to retry these requests.
stripe 描述,只是说请求开始执行才保存,但是超时情况没有说明