案例背景

压测内容:某系统某业务 压测工具:Loadrunner 压测环境:单台WAS应用+单台db2数据库 压测场景:100个并发用户 问题描述:压测前期HPS下降非常厉害,中后期继续缓慢下降,事务响应时间越来越慢,直至内存溢出。

HPS持续走低

事务响应时间

分析过程

查看应用CPU使用率,发现基本已满负荷。

查看JVM曲线,发现JVM空间确实在逐渐贴顶

分析堆转储快照,发现溢出内容居然80%是db2的连接池相关数据。

回想此次压测前,确实改了数据库连接池的缓存语句大小,莫非跟这个有关?

数据源语句缓存大小指定每次连接可以缓存的经过准备的JDBC语句的数量。Websphere ApplicationServer数据源将优化预编译的语句和可调用的语句,放在缓存中供活动连接中使用。如果应用程序调用的语句较多,增加此参数有时可以改善应用程序性能。

根据上面所说,那么调大这个缓存语句大小,理论上应该改善应用性能才对,为何不增反降并且挂掉?

后继续查询官方资料,发现这个参数大小是指每个连接可以使用的语句数,也就是说总的高速缓存大小=语句缓存大小×连接数,如果按上面1000计算,100个连接总缓存为10万条之多。

那么问题就有可能是因为缓存了10万条语句,造成JVM可用空间越来越小,处理效率越来越低,直至内存溢出了?

解决问题

将语句告诉缓存大小调回默认的10条后,系统运行平稳。

优化之后

在知道原因后,做了一次对比测试,在此参数10-50范围内,看看测试结果有什么变化。

业务A100并发,10高速缓存

业务A100并发,50高速缓存

从以上测试结果可以看出,把缓存语句大小从10调整为50,性能反而略有下降。

业务B100并发,30高速缓存

业务B100并发,50高速缓存

从以上测试结果可以看出,把缓存语句大小从30调整为50,性能确实略有上升。

总结

  1. 在preparestamentcache discard值较大时,增加此缓存语句大小确实有助于提高程序性能,但它是以牺牲CPU时间为代价的,在将语句大批量写入缓存后,势必会提高JVM的使用率,GC时会占用更多的CPU时间,如果未调大此参数前CPU就已满负荷,调整后CPU会更加捉襟见肘,从而出现事务时间变慢,乃至内存溢出的风险。
  2. 在测试时发现,不同的场景需要分开分析,设置后提升的效果也不一样,估计和程序本身的SQL写法和数量有关。所以在设置此参数时没有固定值,一定要经过测试,寻求一个合理值。