服务幂等性设计

为什么需要幂等性?

  • 想一想当转账的时候,因为网络原因暂时没收到响应,再次进行转账,如何防止重复性的转账。这就需要幂等设计。
  • 当去自动化安装软件的时候,对于已经安装的软件,再次发出安装软件的命令,是重复安装软件,还是看软件已经安装就返回安装好的结果。

如果从开发角度考虑:

  • 请求执行多次与执行一次的最终结果都是一致的
  • 在业务上,同一用户不能重复下单,商品不超买,不会发生重复转账

请求层面幂等

如果要做幂等,首先对请求进行分类,一般分为读请求和写请求,读请求一般不需要做幂等,读数据本身不会改变数据,因此无需做幂等,而写请求可能对数据造成改变,所有部分写请求需要进行幂等。

从架构层次上,看看那些层会对数据发生改变。

  • 网关,业务逻辑一般不会修改数据

  • 数据访问层可能修改数据,我们只需要对数据访问层进行幂等性设计

对于数据访问层CRUD:

  • 新增数据的时候,通过主键或者某个唯一标识如token,限制某条记录只能插入一次。

  • 更新数据的时候,部分幂等。部分不幂等

    • update user set name='aihe' where id=1; 幂等的
    • update user set age++ where id=1; 非幂等的
  • 删除数据的时候,部分幂等,部分非幂等,在实际删除的时候不要通过相对值来删除,一般在删除之前首先进行一次查询,然后进行绝对删除

    • delete from user where id=1; 幂等的
    • delete from user where uid in bottom 10; 非幂等的

真正需要处理的是update操作。如何处理呢?

  • 方式一:相对值修改转换为绝对值修改。 update user set age=19 where id=1 and age=18; 但是在体量非常大的时候,不是一种好的方式
  • 方式二:部分业务有状态流转,比如说已转账,已收货。每次操作进行状态的修改,满足需要的状态才更新。状态流转比较复杂的时候,一般要引入分布式事务的问题

业务层面幂等

业务层次的幂等如何解决呢?

比如下了一个订单,但是冗余部署了多个进程,这个时候存在并发消费的可能性。对此我们可以尝试将并行操作转换为串行操作,采用分布式锁。

共享资源通过锁来保证。

常见保证幂等性手段

一般在分布式系统中,所有请求都会携带一个唯一的请求流水号,requestNo,在进行操作之前判断这个requestNo是否已经入库了,如果在库中已经存在,代表已经处理过,如果不存在则继续处理。

一般一次操作对应的是一个请求流水号,如果请求流水号不同,代表的是两次操作。

转载于:https://juejin.im/post/5cfeef7b5188257d542e5a2a

猜你喜欢

转载自blog.csdn.net/weixin_33834910/article/details/91478085