# 压力测试:处理提交协同场景慢
# 背景
使用JMeter压测工具,进行200并发压测,发现“处理提交协同”场景很慢,平均10秒,而其它场景则在4秒以内,相对正常。
如果服务器较好的环境,进行200并发压测,“处理提交协同”场景通常都在5秒以内才算正常。
# 分析过程
首先,系统管理员-系统监控检查JVM配置和使用情况,结果很正常。说明不是内存导致缓慢。 ↓↓↓↓↓↓
然后,通过capability.log日志分析,发现提交协同的接口耗时确实是10秒左右。由于可以初步判断,问题慢在服务器端,需要进一步分析慢的原因。 ↓↓↓↓↓↓
在压测缓慢过程中,通过系统管理员-系统监控-Thread Dump抓取慢速线程日志,可以看到大部分请求都卡在事务提交上面,一般卡在事务提交上面都与数据库服务有关。
关键日志如下:
java.net.SocketInputStream.socketRead0
java.net.SocketInputStream.socketRead
java.net.SocketInputStream.read
jm.jdbc.util.buffer.ByteArrayNode.load
...
dm.jdbc.a.a.commit
dm.jdbc.driver.DmdbConnection.do_commit
...
dm.jdbc.driver.DmdbConnection.commit
...
org.hibernate.transaction.JDBCTransaction.commit
最初是怀疑数据库本身未做充分调优,经过项目反馈使用达梦的一键调优脚本调整优化参数后,问题依然没有明显好转。
数据库厂商反馈:一个事务提交,协同产品进行了十多条的SQL运行,怀疑因为SQL执行过多导致提交较慢。协同提交操作使用同一个数据库Connection连接,理论上一瞬间进行多张表写入(写入量不高)是属于正常业务逻辑,执行时间肯定比别的查询慢,但绝对不会慢到10秒。很多项目都压测过,并没有在此处提出过写入过多导致慢的问题。
另外,项目组发现一个奇怪现象:周末无人的时候压测结果明显比工作日压测好一倍以上,“处理提交协同”场景可以在5秒甚至更低。该数据库是多个项目系统共享,工作日多个项目都会使用数据库。
综上分析,怀疑问题在数据库服务器资源负载上,工作日多个项目共享数据库服务器,导致资源紧张。 项目上又进一步监测服务器资源运行情况,CPU和内存无问题。最终怀疑点是压测数据库磁盘上:压测数据库使用普通的机械硬盘,速度较低。
项目上数据库服务器更换高速SSD固态硬盘后,进一步压测,所有问题消失:200并发大部分场景2秒以内响应完成。
↓↓↓↓↓↓
# 总结
如果项目上压力测试,总是出现提交、保存慢,并且存在如下场景,优先分析数据库服务配置是否调优,以及数据库服务器资源是否存在负载瓶颈:
- 通过Thread Dump监控到都卡在数据库事务commit提交上
- 数据库磁盘转速低,硬件资源配置偏小
- 甚至多个系统共用同一数据库
产品代码侧虽然一个事务可能会执行十多条SQL,但这可能并不是问题,N个项目压测都没暴露因为写入SQL太多导致性能问题。
压力测试更多是:要避免多个系统共用数据库情况(排查干扰因子),另外还需要确保磁盘等硬件是高速硬盘。
java.net.SocketInputStream.socketRead
...
org.hibernate.transaction.JDBCTransaction.commit
