[英]Tomcat JDBC Connection Pool: testOnBorrow vs testWhileIdle
For various reasons connections in a pool can become invalid: server connection timeout, network issues... 由于各种原因,池中的连接可能变为无效:服务器连接超时,网络问题......
My understanding is that a Tomcat JDBC Connection Pool does not provide any guaranty about the validity of the connections it provides to the application. 我的理解是Tomcat JDBC连接池不保证它为应用程序提供的连接的有效性。
To prevent (actually only lower the risk) getting an invalid connection from the pool a solution seems to be the configuration of connections validation. 为了防止(实际上只降低风险)从池中获得无效连接,解决方案似乎是连接验证的配置。 Validating a connection means to run a very basic query on the database (eg SELECT 1;
on MySQL). 验证连接意味着在数据库上运行非常基本的查询(例如SELECT 1;
在MySQL上)。
Tomcat JDBC Connection Pool offers several options to test the connection. Tomcat JDBC连接池提供了几个测试连接的选项。 The two I find the more interesting are testOnBorrow
and testWhileIdle
. 我发现两个更有趣的是testOnBorrow
和testWhileIdle
。
First I was thinking that testOnBorrow
is the best option because it basically validate the connection before providing it to the application (with a max frequency defined by validationInterval
). 首先,我认为testOnBorrow
是最好的选择,因为它在将连接提供给应用程序之前基本上验证了连接(具有由validationInterval
定义的最大频率)。
But after a second though I realized that testing the connection right before using it might impact the responsiveness of the application. 但是经过一秒钟后我才意识到在使用它之前测试连接可能会影响应用程序的响应能力。 So I though that using testWhileIdle
can be more efficient as it test connections while they are not used. 所以我虽然使用testWhileIdle
可以更高效,因为它在不使用时测试连接。
No matter which option I choose it seems that they only lower the risk from getting an invalid connection but this risk still exist. 无论我选择哪个选项,它们似乎只会降低获得无效连接的风险,但这种风险仍然存在。
So I end up asking: should I use testOnBorrow
or testWhileIdle
or a mix of both? 所以我最后问:我应该使用testOnBorrow
还是testWhileIdle
或两者兼而有之?
On a side note, I'm surprised that validationInterval
does not apply to testOnReturn
and I don't really get the purpose of testOnConnect
. 另外,我很惊讶validationInterval
不适用于testOnReturn
而且我没有真正达到testOnConnect
的目的。
There is no 100% right answer to this. 这没有100%正确的答案。 It is a matter of trade-off and context. 这是一个权衡和背景的问题。
But considering this as a corner-case, the testOnBorrow gives pretty good assurance. 但考虑到这是一个角落案例, testOnBorrow给出了相当不错的保证。
Now the trade-off with that is that, every time you request a connection, a query (no matter how light-weight) is made to the database-server. 现在需要权衡的是,每次请求连接时,都会对数据库服务器进行查询(无论多么轻量级)。 This maybe very fast, but the cost is still not zero. 这可能非常快,但成本仍然不是零。
And if you have a busy application, with very good database-connection-reliability, then you'll start seeing from the data, that the COST of "validity check on every connection-request from the pool" outweighs the benefits of detecting connection issues. 如果你有一个繁忙的应用程序,具有非常好的数据库连接可靠性,那么你将从数据开始看到,“对来自池的每个连接请求的有效性检查”的成本超过检测连接问题的好处。
It ensures to the max, that you have a good connection before you use it. 它确保最大化,您在使用之前有良好的连接。 Especially considering the cost (retry + manual intervention + loss of workflow etc.) of "not being able to recover easily" from a failed DB operation. 特别是考虑到失败的DB操作的“无法轻松恢复”的成本(重试+手动干预+工作流程丢失等)。
Now imagine if you have the testOnIdle option. 现在想象一下,如果你有testOnIdle选项。 This requires that your connections go idle (dependent on the idle timeout of the connection) before a sanity check can be made. 这需要您的连接在进行健全性检查之前空闲(取决于连接的空闲超时)。
And one last data point is that for some applications, the critical-path is not the "validation query" time (in lower millis hopefully). 最后一个数据点是,对于某些应用程序,关键路径不是“验证查询”时间(希望以较低的毫秒数)。 The applications have bigger issues to deal with. 应用程序有更大的问题需要处理。 And of course, for some applications, that time is very significant. 当然,对于某些应用来说,那个时间非常重要。
Just to let you know, I have just tested this and it is possible to use both testOnBorrow
and testOnIdle
properties. 只是为了让您知道,我刚刚对此进行了测试,并且可以同时使用testOnBorrow
和testOnIdle
属性。
As mentioned above, however, I will be opting to testOnBorrow
uniquely due to the fact that my application is not under heavy traffic and can afford to validate a connection before taking hold of it. 然而,如上所述,我将选择testOnBorrow
唯一,因为我的应用程序没有大量流量,并且能够承担在连接之前验证连接。
As pointed out in comments, testOnBorrow
does not require a validation query. 正如评论中指出的那样, testOnBorrow
不需要验证查询。 If you do choose to keep one it can be a simple select: 如果你确实选择保留一个它可以是一个简单的选择:
jdbc.hive.testOnBorrow=true
jdbc.hive.validationQuery=SELECT 1
If you wish to use testWhileIdle
, you can use the following: 如果您希望使用testWhileIdle
,则可以使用以下命令:
jdbc.testWhileIdle=true
jdbc.minEvictableIdleTimeMillis=1800000
jdbc.timeBetweenEvictionRunsMillis=1800000`
More info on DBCP: https://commons.apache.org/proper/commons-dbcp/configuration.html 有关DBCP的更多信息: https : //commons.apache.org/proper/commons-dbcp/configuration.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.