一,什么是幂等性

所谓幂等性,就是对接口的多次调用所产生的结果和调用一次结果是一致的。即不用担心重复执行。

springcloud 接口v1 v2 spring cloud 接口幂等_springcloud 接口v1 v2

二,业务场景

用户在线下单,下单后系统需要生成对应的工单,用户通过在线工单跟进后续服务状态。
在这个过程中可能会出现了几个问题:

1,用户在前端重复提交,造成同样的订单创建多笔。

2,订单服务调用工单服务由于网络原因或者其他原因失败,发起重试,可造成工单服务创建多笔。

三,技术架构

springcloud 接口v1 v2 spring cloud 接口幂等_springcloud 接口v1 v2_02


上图可以看到订单服务和工单服务都是集群部署,分别部署了两个实例。前端调用后端利用nignx作为负载,同时nignx也有重试机制。

订单服务和工单服务都是采用Spring Cloud架构做的微服务,并利用Ribbon做了重试机制配置。

四,用户重复提交问题

这个问题等同于表单重复提交,一般的解决思路是token机制。

springcloud 接口v1 v2 spring cloud 接口幂等_幂等性_03

也就是说在表单提交之前需要向后端申请token,后端返给前端token的同时需要把token保存到redis中,并设置超时时间。

请求接口时,将此token放在header中或者作为参数,后端判断token是否存在,存在则删除token并正常处理业务逻辑;否则返回重复提交提示。

springcloud 接口v1 v2 spring cloud 接口幂等_微服务_04


这个方案也可以解决nginx重试机制。

五,重试机制问题

如上场景问题2,重试会造成工单生成多笔,所以可以利用数据库的唯一索引,这个就不在展开说了,设置唯一索引就ok。

六,技术架构改造

springcloud 接口v1 v2 spring cloud 接口幂等_springcloud 接口v1 v2_05

在后续为了服务的解耦,一般会引入MQ,而MQ一般会有补偿机制,也就是重试或者人工重试,这个时候建议使用业务主键来做幂等性,也就是上面说的方案2,如果你用消息默认的唯一ID是做不到的,因为每次重试ID都会跟着变。

七,总结

在做微服务架构设计时,需要考虑接口幂等性,在架构初期可以考虑简单方案解决,比如利用数据库唯一索引。随着业务增长和技术提升在考虑复杂方案。