今天遇到一个Websphere性能问题,弄了一上午搞定,留作记录。
Java程序部署在Dev环境,跑起来比较正常,程序打包部署到SIT环境后,出现CPU利用率达到300%多的情况。而且发现一个问题:有一个java程序,是用来从数据库读取数据,在每个字段加上分隔符生成csv文件,再写到一个指定目录上。在dev环境上用时20分钟左右,在SIT上却用了1个多小时。太特么慢了已经严重影响到心情。今天也得来一下性能调优来解决。
程序运行环境: linux 64 位+websphere 7.0+IBM JVM 1.6
1. 首先怀疑是SIT CPU性能有问题,严重肾亏。问了linux管理员,说SIT和Dev环境都是一样一样的。我严重怀疑了一下,程序员就要怀疑一切是不。去他那看CPU监控,发现只要我一跑这个程序,那个CPU就像打了鸡血,从5%升到了300%。看起来CPU性能是没问题,还是从自身找原因吧。
2. 怀疑程序问题,虽然千锤百炼在DEV跑了好多遍,但还是先怀疑一下先。初始目标是定位到java class类,看是哪个程序在给CPU打鸡血。
3. 百度了一下
在linux下面主要使用了这几个命令来操作
1) 看CPU利用率高的进程和线程: ps Hh -eo pid,tid,pcpu | sort -nk3 |tail
结果是这样滴:
[root@websphere history]# ps Hh -eo pid,tid,pcpu | sort -nk3 |tail
4098 4118 5.7
4098 4119 5.7
4098 4120 5.7
4098 4479 5.8
4098 4678 7.4
4098 4600 8.1
4098 4675 8.2
4098 4676 8.2
4098 4229 10.1
4098 4258 54.8
这说明4098 这个process有问题,并且4258这个thread问题所在了。
2) kill -3 pid 会打印线程堆栈的情况。 kill -3 输出到当前进程jvm的标准输出
在linux下生成了一个javacore文件:
/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/javacore.20130308.111115.4098.0002.txt
时间:20130308.111115
进程:4098
很多介绍说用jstack看文件来分析,我杯具的发现我系统环境里用的是是IBM自己写的JDK 1.6没有jstack这个工具,这个工具只能用在sun提供的JDK上。那么他们介绍的说把线程从10进制转化为16进制再去javacore文件里找对应的线程,然后分析问题这个思路就用不上了。
好吧,那么使用IBM提供的一个叫JCA的工具来分析,这个东西全名是IBM Thread and Monitor Dump Analyzer for Java.这是牛x作者的网址:http://jinwoohwang.ulitzer.com/。我下载了一个JCA433来做分析。
javacore文件被打开后各种分析啊,我只看了2部分JVM内存和线程运行分析。
JVM内存:
线程运行分析:
这就看到问题了啊,么么的,内存还有剩余,等待的线程怎么这么多??
142个线程是活动的,都在占用CPU,不过都处于等待状态。那就是说JVM的线程池和数据库连接池配置不合理呀。JVM产生的线程要去连接数据库,可是数据库的连接池太不给力,只有很少资源可以给JVM的线程使用,所以出现了排队等待,这些排队等待的线程还在占用CPU,还没被释放。
我想到的解决方式有2种:1. 增加数据库连接池的数量,允许更多线程同时访问连接池。
2. 调低JVM线程池大小,最好能达到等于数据库连接池数量,这样数据库连接池就不是瓶颈了。
于是去看Websphere admin console里针对这个application的server配置,对比了DEV和SIT,发现就是由于SIT中连接数据库的JNDI的连接池配的太小,DEV中最大数量是100,而SIT中最大数量只有10。把10改为100,再测试,问题解决!