Spring Boot MySQL 连接池踩坑

2019-10-12  本文已影响0人  吉不赛

最近新上了一个服务,用得是Spring Boot + MySQL技术栈。既然涉及到了MySQL,就得考虑连接池,不然MySQL的连接数会打爆。

幸运的是,我们有Spring Boot。Spring Boot默认使用的是Tomcat的连接池。

我遇到的问题是,凌晨1点开始,新的服务就有陆陆续续的报错,报的错误是MySQLNonTransientConnectionException,简单搜一下可以知道,这个错误是因为客户端长时间不使用这个连接,然后MySQL server端会在一定时间内(mysql里面wait_timeout)释放掉这个连接,但是这个时候,客户端是不知道连接已经被释放了,所以再次发起请求的时候就会有这个错误。

问题已经明确了,那么是如何出现这个问题呢?

这个问题出现还比较偶然。为什么说偶然呢?因为Spring Boot 默认使用的Tomcat连接池有一个属性testOnBorrow, 这个属性为True的时候,客户端在使用一个连接前会先测试下这个连接是否有效。如果连接已经失效,则会重新获得连接。

那么我也是用了Tomcat的连接池,为啥我会遇到这个问题呢?

因为我用了手动配置DataSource,因为要用架构组提供的一个打点,所以手动配置了DataSource,这样就导致testOnBorrow 没有置为True。然后就悲剧了。。。。

这里分享了一篇我查问题参考的文章,从源码角度讲解了数据源和连接池的初始化过程,讲解很详细而且准确。链接在这

前面提到了testOnBorrow 属性会在每次请求db前测试下连接是否有效,这样其实是有点低效的。所以我用了另外一个连接池HikariCP。这个连接池配置也非常简单,只要把对应的类引入到classpath就行了。那么HikariCP是怎么解决上面那个问题呢。查看文档可以看到有一个属性是maxLifetime,这个属性就是标识了这个DB连接如果不使用后多长时间被回收。这个值应该设置得小于数据库的wait_timeout。

经过这次教训,算是对MySQL连接池有了个基本的认识。

上一篇下一篇

猜你喜欢

热点阅读