最近做的一个运营商的项目,用了Camunda的工作流引擎来进行任务的编排与执行,每隔15分钟会运行一个任务,获取大约800多个网元的过去一段时间的性能指标,并根据预先定义的规则表的指标判断规则,来识别网元是否有告警,每次任务运行时间都比较长,大概需要6到7分钟完成。除此之外,这个工作流引擎还有很多其他的任务会不定时的运行,整个引擎的负荷比较高。然后在最近一段时间内,频繁出现无法访问Camunda API的问题,报错信息是HTTP 500 Error,报错信息是message: "Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection",type: "CannotCreateTransactionException"
因为我们是通过Springboot集成的方式来运行Camunda的,根据这个错误信息,我想到了是否因为数据库连接池不足导致的。在网上也搜索了一下,看到springboot 2.x版本是继承了HikariCP来提供JDBC的连接服务,默认的连接池大小是10。我们的Camunda访问的后端数据库是mysql,因此我也登陆到mysql上面,用以下命令来查看当前的总连接数量以及在用连接数量:
select count(host) from information_schema.processlist where host like '123.123.123.123%';
select count(host) from information_schema.processlist where host like '123.123.123.123%' and command not like 'Sleep';
这个语句里面的123.123.123.123代表的是camunda服务器的地址,command如果不是sleep表示这个连接不是休眠的,而是在用的连接。
从以上命令结果可以看到,camunda当前只创建了一个大小为10的连接池。因为我们的定时任务比较复杂,运行时间比较长,所以会一直占用几个连接而没有及时释放,加上其他任务运行时也会消耗一些连接,因此会不时出现以上遇到的错误。
找到问题原因之后,解决办法就很简单了,在camunda的springboot项目中,application.properties文件里面加上一个配置datasource.hikari.maximum-pool-size=100即可解决。
一个小插曲,当我把这个解决方案告诉运维人员,让他们修改配置,但是他们修改错了,以为是修改datasource.max-active,结果问题一直没有解决,我也额外花了不少时间分析,看来以后要确认配置的修改是按照方案执行的才可以。