幂等就是一个操作,不论执行多少次,产生的效果和返回的结果都是一样的。
要做到幂等性,从接口设计上来说不设计任何非幂等的操作即可。
例如很常见的支付下单等场景,由于分布式环境中网络的复杂性,用户误操作,网络抖动,消息重复,服务超时导致业务自动重试等等各种情况都可能会使线上数据产生了不一致,造成生产事故。
- 业务字段加唯一约束(简单)
- 令牌+唯一约束(简单推荐)客户端每次在调用接口的时候,需要在请求头中,传递令牌参数(令牌可以存储到redis中),每次令牌只能用一次。一旦使用之后,就会被删除,这样可以有效防止重复提交。
- mysql的insert ignore或者on duplicate key update(简单)
- 共享锁+普通索引(简单)
- 利用MQ或者Redis扩展(排队)
- 同步锁(单线程,集群可能会失效)
- 分布式锁如redis(实现复杂)
- 其他方案如多版本控制MVCC 乐观锁 悲观锁 状态机等。。。
- 对客户端请求排队或者单线程都可以处理幂等问题,需要根据具体业务选择合适的方案,但必须前后端一起做,前端做了可以提升用户体验,后端则可以保证数据安全。