今天测试时,遇到一个问题:扣款时,能将余额扣到负数(正常来说是余额<付款的金额,就跳转到充值页面)
刚开始以为是没有对余额进行加锁的问题(我以为的加锁:看下列步骤2)
接着就查看日志发现,付款100时
第一次付款100,后台扣减100;第二次付款100,后台扣减了200;第三次付款100,后台扣减了300
原因:后台把前面的金额累计相加之和再扣减了
关于对于余额加锁的问题,摘抄了一个网友的回答:
链接:https://www.zhihu.com/question/61484424/answer/190047759
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2、找出关键代码进行调优
步骤1:
正常的红包扣减流程是:加锁、查询、扣减、释放,但是lock记录过程,并发度下降了,这个就导致并发下降。
通常情况下是先查询(一次网络交互),再发更新语句(一次网络交互),代码层面感觉不出,在高并发下有实质的区别。
优化:
如果一次性的网络交互与数据库的交互就完成上面两个动作,那么并发就提高了。
所以可以通过数据库的where条件自己直接判断,符合要求就直接在数据库里面update更新(例如执行更新以后总金额大于100就直接返回0,然后在把成功与否的信息返回给我们,这样每秒的吞吐量tps就可以提高很多很多。例如从1000提高到4000.
当然你还可以采用其他办法,批量,缓存等,目的是减少数据库网络交互。
步骤2:
通过步骤1优化,tps到了4000,感觉比较难上去了,这个时候可以进行【水平扩张】。
优化:
将红包记录单独出来,1000块钱的红包类似于分布式一样分为10个100块的请求分布到10个不同的记录去。由原来的一个行锁分布到10个去,1个进程分布到10个去。
更新的能力优化:从业务逻辑或者代码层面优化,减少更新频率
查询的能力优化:索引优化(活动id加到where里面,建立索引),子活动做一些前缀索引之类的,like查询之类的减少查询频率,通过一些优化尽量不让访问。
这样tps可以从4000提高到了20000
步骤3:
热点问题的话:经常处理是进行【拆分】。可以使用内存模式、队列技术进行再进一步提高tps,有些规则匹配可以放到内存中。(数据量尽量少,维度可做一些拆解)
浙公网安备 33010602011771号