BUG 描述:
Acs(通用过滤系统)整体性能曲线波动幅度很大,最大幅度超过65%!!!
以下是截取其中一段时间性能波动曲线回忆版(吞吐量是每隔10s统计一次的平均值)
BUG的影响:
Acs整体的处理性能始终上不去,达不到现网要求的1w/s。
BUG的发现过程:
采用性能测试工具压测svr,待系统稳定后,每10s采集一次系统的平均吞吐量,发现曲线波动非常大,不符合正常的性能曲线
BUG的分析与解决
BUG的分析:
Acs的svr维护一个session会话,每当acs接受一个请求的时候就会往会话里追加该请求的一些信息,这些信息中间包含一个时间戳,记录这个请求开始处理的时间。每当acs处理完一个请求的时候,就会去session里面去取出这个请求当时保存的信息,在组包返回给前端。
Acs的svr还有一个超时处理线程,该线程每隔3s就会去session会话里遍历读取5000个请求,进行超时判断,如果超时,就返回给前端该请求已经超时。注意此操作将要耗费相当长一段时间!
此时,问题就出现了,我们可以简单的用一个图来描述一下
Session会话就是我们的临界资源,此时一共有三个线程抢着给它上锁,他们分别:
1)request线程:该线程从gnp的request队列里取请求后解包,将一些不需要与后端交互的信息暂时写到session会话里面,我们暂时就叫它request线程。
2)response线程:该线程收到后端应答后从session会话里面取出request线程之前存入的对应的信息进行组包返回扔到gnp的response队列里
3)超时处理线程:该线程要对session会话里面的超时请求定期进行清理。
三个线程具有平等的权利,谁抢到了全凭运气。于是一场无硝烟的战争开始了。
我想大家应该都明白原因在哪里了:每当超时处理线程抢到这个资源的时候,实际工作的线程(request线程和response线程)就一直处理等待状态,此时吞吐量明显会下降,反之,当超时处理线程没有抢到的时候,咱的吞吐量还是很OK的。
BUG的解决:
1) 方法一:缩短超时处理线程每次取出的请求个数,这样就可以减少超时处理线程加锁的时间,这样实际工作的线程就回有更多的机会和时间获取sesson会话的锁,从而提升实际的处理能力
2) 方法二:Session会话其实就是一个队列,根据队列的先进先出原则,我们何不之前做一个判断?每次取出队列尾部的请求进行超时判断,若尾部都不超时,那么就说明整个队列都没有超时,若尾部超时了,结合我们的方法一,取出一小部分请求即可。所以我们采用的是这个。
BUG经验沉淀:
有硬件的,当然也软件的。
硬件的:加锁并不能保证“安全”。这也是一个关于线程安全的问题,尽管我们的系统已经加锁了,但是就不能说没有问题了,对于一个高并发的系统,还是结合实际的处理情况来决定加锁的时长甚至是锁的分配。
软件的:发现问题的过程中,对问题要有敏锐的嗅觉,在呈现问题时需要提供非常有力清晰的证据,推动问题的解决则是基于本身对版本质量的强烈的责任意识。任何一个环节的缺失都将会将BUG遗漏掉。所以说,测试不仅仅是一门计算机科学,而是一个集合计算机,沟通,管理等多门综合的学科。虽然说的和教科书似得,但的确是这个BUG从解决到发现的整个过程Lisa对测试的进一步的理解
多线程加锁,别锁太长~~~
最新推荐文章于 2024-08-28 23:36:47 发布