我已经阅读了很多关于从休眠会话自动重新连接到 mysql 的问题的帖子。其他人提到增加mysql wait_timeout(不是我最喜欢的),使用autoReconnect = true(不推荐),测试连接等我目前正在尝试一些选项,但我想问是否有人使用tomcat的连接池有一个坚如磐石的解决方案(不是休眠的c3po)。我正在寻找最防弹的 jndi 设置,即使它们不是最好的性能调整。
非常感谢,
问候
很好的问题。我曾经为这个问题而挣扎。对于几乎所有问题,stackoverflow 上最常见的答案是“取决于……”。我不想这么说,但没有比调整连接池更相关的了。这确实是一个供需游戏,您的连接请求是需求,而供应是 MySQL 可用的连接数。这真的归结为您的主要关注点是防止从池中返回陈旧的连接,还是您关注的是确保 MySQL 不会因空闲连接而过载,因为您没有足够快地杀死它们。大多数人躺在中间的某个地方。
如果您真的理解为什么有人会选择任何一种连接池配置,那么相信我,您将停止搜索“Rocket Solid”设置,因为您会知道这就像在谷歌上搜索您的商店的商业计划;这完全取决于您获得了多少连接请求以及您愿意提供多少持久连接。下面我举例说明为什么要使用某些设置。我引用了您必须在 Context.xml 文件的“上下文”标签的“资源”标签内更改的变量。在最底部可以看到示例完整配置。
低流量
在这种情况下,您对应用程序的请求很少,因此连接池中的所有连接很有可能会失效,并且应用程序通过失效连接发出的第一个请求将导致错误。(取决于您使用的 MySQL 驱动程序,该错误可能解释接收到的最后一个成功数据包超出了数据库的 wait_timeout 设置)。所以你的连接池策略是防止死连接被退回。以下两个选项对于低流量站点几乎没有副作用。
在终止连接之前等待更长的时间- 您可以通过更改wait_timeout
MySQL 配置中的值来做到这一点。在 MYSQL 工作台中,您可以在管理员 > 配置文件 > 网络下轻松找到该设置。对于具有大量流量的站点,通常不建议这样做,因为它可能导致池中总是充满大量空闲连接。但请记住,这是低流量场景。
测试每个连接- 您可以通过设置testOnBorrow = true
和来做到这一点validationQuery= "SELECT 1"
。性能呢?在这种情况下,您的流量很低。测试从池返回的每个连接都不是问题。这意味着一个额外的查询将被添加到您在单个连接上执行的每个 MySQL 事务中。在低流量网站上,这真的是您担心的事情吗?您的连接因为没有被使用而在池中死掉的问题是您的主要关注点。
中等流量
validationQuery = "SELECT 1"
, testWhileIdle = "true"
, andtimeBetweenEvictionRunsMillis = "3600"
或任何你想要的间隔。对于非常低的流量,这绝对需要更多的工作。想想看。如果池中有 30 个连接,并且在 1 小时内只有 4 个被调用,那么您可以使用以前的testOnBorrow
方法轻松检查每个请求的所有 4 个连接,而性能影响很小。但是,如果您改为使用“每小时检查一次”的方法,那么当仅使用 4 个连接时,您会发出 30 个请求来检查所有连接。高流量
wait_time
这样您就不会在数据库上出现大量空闲连接。下面是一个小伙子的例子,他说他每天有多达 10,000 个空闲连接用于繁忙的站点,因此他想降低 wait_timeout降低繁忙站点的 wait_timeout示例 Context.xml 配置
<Context>
<Resource name="jdbc/TestDB"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1"
validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="100"
minIdle="10"
maxWait="10000"
initialSize="10"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="30000"
jmxEnabled="true"
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
username="root"
password="password"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mysql"/>
</Context>
示例 web.xml 配置
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<description>MySQL Test App</description>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
有关 Tomcat 池属性的文档以调整Tomcat 池