什么是幂等问题?
先说下什么是幂等,幂等性是数学和计算机科学中的概念,用于描述操作无论执行多少次,都产生相同结果的特性。在软件行业中,广泛应用该概念。当我们说一个接口支持幂等性时,无论调用多少次,系统的结果都保持一致。
一般我们在系统中,幂等可能存在两种类型的问题:
-
接口幂等:常说的接口防重复提交。
-
消息队列幂等:如何保障消息队列客户端对相同的消息仅消费一次。
如果不做防重复提交或者幂等,可能会导致以下问题:
-
数据重复处理:如果用户在某个操作还在处理中时重复提交请求,可能会导致相同的数据被处理多次,造成数据的重复操作和处理逻辑的错误。
-
重复写入:在某些场景下,请求可能触发对数据库或其他存储系统的写入操作。如果请求被重复提交,可能会导致相同的数据被重复写入,破坏数据的一致性。
-
资源浪费:重复提交请求可能会导致服务器资源的浪费。如果请求处理的时间较长,重复提交会占用服务器的处理能力,增加服务器的负载,降低系统的性能和吞吐量。
-
业务逻辑错误:在某些业务场景下,重复提交可能会导致业务逻辑错误。例如,如果用户在生成订单的过程中重复提交订单请求,可能会导致生成多个相同的订单,引发订单的混乱和错误。
接口防重复提交
举个例子,你在淘宝上下单某个商品,然后提交订单时由于你快速点击多次,或者网络波动提交服务端多次请求,如果淘宝服务端没有做相关防重复提交处理,那么就有可能生成多笔相同的订单。
如果做了幂等处理,除了第一次正常请求外,第二次乃至更多次应该返回错误,比如说提示语“重复提交失败”等;再或者返回“提交成功”,但是真正保存数据库的只有一次请求。具体使用哪一种需要看程序设计以及产品逻辑。
消息队列消费幂等
消息队列在消息传递过程中,由于网络延迟、系统故障或其他异常情况,可能会导致消息被重复消费的问题。造成消息重复消费的问题比较多,我们就不细分析了,知道有这种场景就好。
通常情况下,我们认为消息中间件是一个可靠的组件。这里的可靠性指的是,只要消息被成功投递到了消息中间件,它就不会丢失,至少能够被消费者成功消费一次。这是消息中间件最基本的特性之一,也就是我们通常所说的 “AT LEAST ONCE”,即消息至少会被成功消费一遍。
这也就说明,如果服务端出现了客户端是否消费成功的疑问时,会让客户端再次消费。
造成的问题也比较明显,如果订单支付消息被重复消费,可能会导致业务逻辑的错误执行。例如,系统可能会多次发放优惠券、赠品或其他奖励,使得商家承担不必要的成本或资源浪费。