程序响应慢了,看看资源池
资源池,是指线程池、数据库连接池、redis连接池、http连接池等程序的池化资源。
资源池,好的地方是,一方面解决了频繁创建销毁资源的开销;另一方面对资源加了限制,防止耗尽系统所有资源。
不好的地方是,当某些业务因为异常,占用资源池较多资源时,其他业务获取不到资源或获取时间变长,慢点就出现了。现象会表现在资源池,当然,这不是资源池的错。
慢,通常会表现为某些请求响应慢或无响应。现在系统,大量使用线程池,线程是基本工作单元,不管是什么业务因为什么资源池引起的慢,最终都会表现为线程池线程不足,大量线程卡在某个点上。
那要怎么排查呢?
既然最终表现都是线程卡在某个点上,对Java应用来说,通过jstack PID输出堆栈信息,再通过分析慢的线程池每个线程堆栈信息,就可以找到具体卡在哪行代码上。
比如,最近我们的用户查费缴费Java Web程序,用户反馈打开页面空白,我们自己检测后端程序心跳也无响应,基本可以肯定是Web容器(我们用的undertow)线程池耗尽了。通过jstack输出,分析Web容器线程池所有线程的堆栈信息(linux下用grep和count),最终发现卡在通过http请求向外部系统获取广告上。这里http请求没有设置读取超时时间,外部系统一直无返回,线程就卡在这里了。
再有,我们另外一个通讯层程序,突然出现其他系统通过http向它发送请求总是超时,最终也是通过jstack输出,分析发现卡在从HttpClient连接池获取连接上。根本原因可以参考RestTemplate实例化问题
其他一些Java应用慢排查思路可以参考Java后端服务明显变慢诊断思路