电商平台下高并发经典问题在实际的项目中需要积极的思考,高并发场景下接口幂等性,分布式事务,数据库锁,分布式事务,乐观锁,悲观锁,事务场景都是需要在实际项目中进行思考和提出解决方案。本文就讲项目中遇到的问题一一做详细分析和寻找解决方案。
接口幂等性定义和解决方案
(1)定义:
什么是接口的幂等性,如果是第一次听到的小伙伴可以简要的阅读下,在java开发中接口的幂等性主要讲的是接口在1次和多次调用的系统的数据影响是一样的。
接口的幂等性实际上就是接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的。有些接口可以天然的实现幂等性,比如查询删除接口,但是插入更新接口等需要考虑接口幂等性,
(2)场景:
一个订单创建接口,第一次调用超时了,然后调用方重试了一次
在订单创建时,我们需要去扣减库存,这时接口发生了超时,调用方重试了一次
当这笔订单开始支付,在支付请求发出之后,在服务端发生了扣钱操作,接口响应超时了,调用方重试了一次
一个订单状态更新接口,调用方连续发送了两个消息,一个是已创建,一个是已付款。 但是你先接收到已付款,然后又接收到了已创建
在支付完成订单之后,需要发送一条短信,当一台机器接收到短信发送的消息之后,处理较慢。消息中间件又把消息投递给另外一台机器处理
(3)解决方案:
1、去重表
去重表设计思路主要讲的是更新或者插入数据之前先在去重表中插入一条记录,并按照数据内容设计唯一索引,这样如果接口已经调用一次重复调用就会引发键值重复,异常处理中可以作重复相关处理或者引发数据异常数据回滚。
2、全局唯一ID
如果使用全局唯一ID,就是根据业务的操作和内容生成一个全局ID,在执行操作前先根据这个全局唯一ID是否存在,来判断这个操作是否已经执行。如果不存在则把全局ID,存储到存储系统中,比如数据库、redis等。
但是如果存储在数据库中如果按照select+update可能会发生并发问题,需要特别注意,如果这种场景下需要考虑分布式锁或者采用同步机制。如存在数据库中在插入时重复插入就会发生异常回滚。
更新时按照唯一键值进行更新,但是需要注意的是在更新操作下可能会发生重复操作,例如设置订单状态支付成功和创建两个操作可能会重复执行,需要结合数据库字段或者状态机实现功能。
3、数据库字段约束
数据库字段约束主要用版本号控制,状态机约束,字段约束,其实从整个的实现思路来说都是采用数据库字段进行做文章。
a、版本号控制主要用于并发情况下做扣减或者或者操作数据,如果没有版本号两个并发操作会出现读取到数据一致,但是扣减之后本来处理的扣将两次操作的和但是现在值是最后一个操作的值,加了版本号就会防止这种情况发生
b、只有在某种字段满足特定条件的情况下才能进行指定字段的处理,例如在状态为未支付的情况下才能进行金额扣减,需要在数据库where字段中进行处理。
c、状态机思路在电商订单流转或者在状态机很复杂情况下才能进行,思路就是利用有限状态机在各个情况下状态变更需要依赖制定状态机流转,满足有效状态机才能进行状态变更,另外采用有限状态机可以统一管状态变更,而不是把状态变化分散到各个部分不便于管理。
本节到此,下次分享电商平台高并发思考-事务(2)
网友评论