昨晚测试环境遇到了一个问题,情况是这样的:
1、系统访问了两个特定的帆软报表之后,其他所有请求被阻塞,导致 nginx 报 504 的错误。
2、帆软报表仍然能访问。
分析、猜测与定位:
1、既然帆软报表仍然能访问,说明 tomcat 和 nginx 服务正常。
2、既然特定的报表有问题,把特定的报表文件设置为空,看看是否是仍然出现问题。试了一下,设置为空的帆软报表被访问,不会导致上述问题。那说明,确实是这两个报表导致了请求阻塞。这两个报表 cpt 的特征是有很多数据集。
3、所有获取后台数据的请求被阻塞,有点像数据源相关出问题了,初步猜测问题出在获取数据库的连接那块;帆软报表里数据集越多,帆软应用需要获取的数据库连接数就越多。
jstack 查看 tomcat 进程的线程情况:
1、很多线程都在从数据库连接池获取连接的方法 getConnection 上阻塞
org.apache.tomcat.dbcp.pool2.impl.LinkedBlockingDeque.takeFirst
2、猜测是帆软应用的数据库连接池,从应用系统的数据库连接池把 Connection 拿完,导致应用系统获取数据库连接动作被阻塞。
继续尝试:
1、把帆软的数据库连接池的最大连接数设置为 1,问题不复现。
2、查看应用数据系统的数据库连接池最大连接数,尽然未配置。翻了下连接池的源码,默认最大连接数 8。把应用系统的数据库连接池的最大连接数,配成与数据库最大连接数一致,100。问题修复。
总体来看,根本原因就是应用系统的数据库连接池的最大连接数等相关参数未配。
往往越是简单的配置,越是最难排查的...
上午的 3 个小时耗没了!