压力测试优化总结
2019年5月7日至5月14日之间,对即将上线的模块进行了压力测试,通过压力测试,对系统参数、部分设计思路和实现代码进行了优化,交易的并发量由每秒几笔最终提升到每秒60笔以上,并且隨着并发数量的提升,交易始终保持较高处理速度,以下是对本次压测优化进行总结。
背景介绍:当校验程序并发处理一个规则时,为了保证资金金额的正确性,系统只允许处理一笔,其余的交易等待,每次等待的时间3毫秒,循环处理300次,循环结束,循环结束后还没处理的线程登记超时表,执行原来的数据库逻辑验证,后续交易均通过数据库校验。
一、关键参数优化:
问题表现:20个线程并发压力测试压三个规则,压一小段时间后,三个规则陆续登记超时表,交易通过查询数据库验证。
原因分析:通过分析日志,前期交易可以正常执行,执行大约1分钟后,陆续登记超时表,后续由数据库验证,经过分析原因:由于超时时间设置太小,压测一段时间后,三个线程陆续出现等待超过300毫秒后,均登记超时表,后续交易均通过数据库校验。
优化方式:增大循环处理次数为3000000,等待时间约2.5小时。
处理结果:后续测试均未出现超时现象,直到交易结束,但是并发量仅有五笔左右。
二、根据日志时间,优化处理耗时比较长的逻辑
问题表现:通过参数的优化,交易可以正常进行,但是处理速度依然很慢,并发响应需要16-20秒(并发场景)
原因分析:通过日志分析,发现真正进行限额校验的时间只有7毫秒,而与REDIS建立连接消耗的时间大于200毫秒。
优化方式:并不需要每次校验都初始化连接,redisCluster本身具有连接池,只需要第一次建立连接就可以,优化代码为只需要第一次调用初始化连接池。
优化结果:调用响应时间大幅降低,并发量达到20笔每秒。
三、优化IO输出:
问题表现:虽然没有太大块的时间消耗,但是性能还是不能达到满意。
原因分析:通过分析代码,可能造成性能下降的因素是I/O输出,尽量减少I/O输出可以提高性能。
优化方式:1:尽量减少日志的输出;2:对从数据库中需要读取的配置类信息每次只查询一次,后续交易从缓存读取
优化结果:单规则串行执行处理时间比较稳定,且不超过100毫秒,单规则5线程并发量达到40笔每秒;单规则10线程并发量下降到25笔每秒;单规则30线程并发下降到13笔每秒
四、排队算法优化:(后面的压测在虚拟桌面内压测非(服务器),并且仅压测REDIS处理部分,压测结果不是和测试服务器测试的结果不一样)
问题表现:虽然经过上述优化提高了性能,但是随着并发量的提高,性能下降严重,如何随着并发量的提高,始终保持高性能执行呢?
原因分析:在并发量高的情况下,排队的线程都会在固定时间(3-10秒内随机值)去获取锁,导致产生大量并发交易请求REDIS,这样的结果是REDIS性能下降,带宽被占用,服务器性能下降。
优化方式:原来抢占式获取锁的排队方式改为有序的静态队列(ConcurrentHashMap+ConcurrentLinkedQueue,查询,新增,删除操作时间复杂度均为O(1),支持高并发),以空间换取时间,当一个服务服务执行结束以后,主动通知后续服务,服务按照请求先后顺序依次执行
优化结果:降低了REDIS的压力,节省了带宽,提高服务器的执行效率,并且支持横向扩展,缺点,对服务器内存有要求,但是要求不大。云桌面压力测试结果如下:虽然随着线程增加,性能缓慢下降(JVM初始化内存比较小导致)。
五:执行顺序优化。
问题表现: 当并发达到500个线程的时候,出现数据库连接获取失败异常。
原因分析: 在进入REDIS执行之前,需要先到数据库查询参数、是否存在有脏数据、redis状态是否异常,然后才设置分布式锁、排队处理,由于数据库连接资源不足以处理500个并发,导致出现异常。
优化方式: 优化处理顺序,最先设置分布式锁,然后排队处理,只有开始处理验证,才查询参数、是否存在有脏数据、redis状态是否异常,把并发压力阻挡在分布式锁外,
优化结果:优化以后,不再报错,但是每秒只能处理2笔交易,远远小于目标并发;继续减少大日志输出后,每秒也仅能处理5笔。
六:JVM优化
问题表现: 500个并发完成以上的优化以后,系统性能依然很低,从日志输出可以看出,刚开始处理很快,但是处理一段时间以后,系统卡顿严重,从输出日志页可以看出卡顿的时间超过300毫秒。
原因分析:通过分析卡顿,并且日志中有大块时间没有日志输出,应该是JVM进行垃圾清理,频繁的垃圾清理的原因应该是高并发场景下内存不足。
优化方式:通过查看Eclipse参数发现最大内存256M,初始化内存64M,把两个空间全部改为1G.
优化结果:加大内存后系统处理速度显著提升, 最高可达44笔每秒。
后续当并发达到1500笔时,会报内存溢出或者内存不足,但是使用的工具最高支持1G内存,没办法再作更高并发的压测。规则串行压力测试结束,通过优化,高并发场景下交易始终可以四十多TPS的速度运行,基本达到优化效果。
七:优化结果检验:
接下来是多规则并发测试,测试结果随着线程的增加,处理速度缓慢提升,后续在测试环境进行的压力测试并发数也由最高40个并发提高到了60个左右,并且随着并发数提升处理速度缓慢提升,和在虚拟桌面测试的规律基本一致,达到了优化预期效果。
总结:虽然系统仍有继续优化的潜力,如:排队算法深入优化、JVM参数分代内存优化、垃圾收集器优化、连接池优化等手段对系统深入优化、提高性能,但是通过在压力测试过程中完成的优化参数、优化耗时逻辑、优化IO输出、优化算法、优化处理顺序、优化JVM,实现了对REDIS压力小、节省带宽、节省服务器资源消耗、可扩展并且随着交易并发量提高始终保持高处理速度得交易,达到了预期目标,满足了现有的需求,因此不再深入优化。