Open cs50Mu opened 4 years ago
如果一个操作执行多次跟执行一次的效果是一样的,那么这个操作是幂等的
which means that they can be called any number of times while guaranteeing that side effects only occur once.
一个简单的场景,A 服务通过 http 调用 B 服务来完成充值操作,当调用超时时,此时有两种可能::
一般当调用超时时,我们的策略是重试,再发起一次同样的请求,但若上次的充值已经成功了,而且被调用的接口不支持幂等的话,那么会导致重复充值的问题。
反之,若接口支持幂等,根据幂等的定义,执行多次的效果跟执行一次是一样的,若出现超时调用者可以放心重试。
读请求是天然幂等的,这个无需解释
对于原本非幂等的操作,需要想办法将它改造成幂等,一般是通过引入一个唯一ID来标识一次操作,不同的操作需要使用不同的ID,这是一个调用者和被调用者之间的约定,这意味着如果调用者不遵循约定,非要在不同的操作里使用相同的ID会出问题。
在分布式系统中,若各调用方自己生成自己的唯一ID来标识操作,则有风险会出现多个调用方使用了同一个ID(虽然可以通过约定不同的调用方使用不同的前缀来保证但并不是一个稳定的解决方案),那么为了解决这个问题,需要引入一个全局ID生成器,每个调用方在发起操作请求前需要先请求全局ID生成服务获取一个ID。
在发起请求时,这个ID可以放在body里,也可以放在header里
需要有个地方存储目前收到的唯一ID,假设叫idempotency_key
idempotency_key
是否存在idempotency_key
对应的resp body返回idempotency_key
的映射关系存下来后,返回resp这里有两个实现细节::
idempotency_key
用什么存储机制?文件系统?数据库?Redis?idempotency_key
显然没有必要一直存着,多久清理一次?如何清理?
https://idontbyte.jaun.org/blog/2019/09/Idempotence
https://ieftimov.com/post/understand-how-why-add-idempotent-requests-api/