关于分布式系统中的并发问题
问下各位,在分布式系统中,我的模块中的接口属于被调用的,用户的操作不会直接涉及我的模块,一般由其他模块调用我。这种时候我要如何考虑我模块中的并发问题。
我现在负责的会员模板有一个余额消费的功能,由订单模块,调用我会员消费,我只需要将订单模块传给我的消费金额和相关会员账号进行 扣款处理即可,项目经理让我排查一下其中出现的并发场景。但是我不太清楚分布式系统中的,并发问题是怎么产生的。
问下各位,在分布式系统中,我的模块中的接口属于被调用的,用户的操作不会直接涉及我的模块,一般由其他模块调用我。这种时候我要如何考虑我模块中的并发问题。
我现在负责的会员模板有一个余额消费的功能,由订单模块,调用我会员消费,我只需要将订单模块传给我的消费金额和相关会员账号进行 扣款处理即可,项目经理让我排查一下其中出现的并发场景。但是我不太清楚分布式系统中的,并发问题是怎么产生的。
你们扯上 tcc 是什么鬼,lz 只是要保障自己的模块安全就可以了.
要 tcc 之类的,就要联动你的订单模块一起从整体上来看架构了。你们这个没个架构师来把关么,不要随便用 tcc
每个订单的扣款要考虑幂等,不能重复扣款。
模块中如果有多个消费者共享的资源,要考虑加锁或者 CAS,比如领券的场景。
RPC 调用,账户额度和订单状态要考虑一致性。
借助其他实现了分布式一致性协议的组件也可以实现分布式锁。
就你这个场景,两个对同一个用户的扣款请求,可能被路由到你服务的两个完全不相关的进程上,这两个进程内各自处理自己的扣款操作,比如是检查余额和扣款俩操作,二者均检查本次扣款余额充足没问题,结果可能会扣款变成负数。这时候就需要分布式锁来强制两个用户的扣款操作顺序进行。
这个场景你如果不考虑,那么可能出现的问题是:一,没上事务,余额表的变动历史将乱成一锅粥;二,上了事务,但在扣余额的时候没做二次验证,余额会被口称负的。
解决方法如下,顺序是从简单到复杂,所有方法都要先有事务(单节点事务):
一、乐观锁,只适合单节点应用。这个太常见了,而且你也不是单节点应用,就不细说了。
二、实时动态扣费,适合订单模块(不是你的模块)并发量不是特别高的情况。你在扣费的时候不直接扣,先去查下当前余额,如果扣完不为负,再扣费。你的接口的返回结果不是 void,也不是 true/false,而是一个对象,包含这些字段:是否扣款成功、扣费前的实际余额、扣费后的实际余额。
三、最终一致性,适合订单模块超高并发量的情况。直接扣费,返回结果总是成功,如果扣成负的了,发事件通知,让其他模块去做补偿(或者啥也不干就允许余额为负,或者再通知订单模块去取消订单)。
最后说一句,看见分布式事务或者分布式锁的回复,请直接忽略,这是老早就被淘汰的技术。
里很多人是不是根本没有做过业务,只看过书,一堆什么分布式锁都出来了
这是要梳理场景,不是解决方案。何况场景没有,解决方案是怎么意淫出来的
并发问题主要考虑两点,这个接口短时间相同请求发起两次请求,这个接口被不同请求同时调用
做业务时,开启事务,select for update 锁住对应的单号,用户的余额,然后在本事务中做业务,完事了 commit
这种同一单号的并发请求过来,一定会被挂起,执行代码中增加判断订单状态的逻辑就好了,如果本单状态为成功则幂等返回成功。
你这是有热点会员吗,同一个会员做大量余额扣减?如果是这样完全可以考虑用子会员的方法实现,也不差的