tomcat 7.0.42 pooling, hibernate 4.2, mysql 坚如磐石的自动重新连接解决方​​案

Posted

技术标签:

【中文标题】tomcat 7.0.42 pooling, hibernate 4.2, mysql 坚如磐石的自动重新连接解决方​​案【英文标题】:tomcat 7.0.42 pooling, hibernate 4.2, mysql rock solid autoreconnect solution 【发布时间】:2013-08-07 09:02:51 【问题描述】:

我已经阅读了很多关于从休眠会话自动重新连接到 mysql 的问题的帖子。其他人提到增加mysql wait_timeout(不是我最喜欢的),使用autoReconnect=true(不推荐),测试连接等。我目前正在尝试一些选项,但我想问是否有人使用tomcat的连接池(不是hibernate的c3po)有一个坚如磐石的解决方案。我正在寻找最防弹的 jndi 设置,即使它们不是最好的性能调整。

非常感谢,

问候

【问题讨论】:

【参考方案1】:

很好的问题。我曾经为这个问题而挣扎。对于几乎所有问题,*** 上最常见的答案是“取决于……”。我不想这么说,但没有比调整连接池更相关的了。这确实是一个供需游戏,您的连接请求是需求,而供应是 MySQL 可用的连接数。这真的归结为您主要关心的是防止从池中返回陈旧的连接,还是您关心的是确保 MySQL 不会因空闲连接而过载,因为您没有足够快地杀死它们。大多数人躺在中间的某个地方。

如果你真的理解为什么有人会选择任何一种连接池配置,那么相信我你会停止搜索“Rocket Solid”设置,因为你会知道这就像在谷歌上搜索你的商店的商业计划;这完全取决于您获得了多少连接请求以及您愿意提供多少持久连接。下面我举例说明为什么要使用某些设置。我引用了您必须在 Context.xml 文件的“上下文”标签的“资源”标签内更改的变量。可以在最底部看到示例完整配置。

低流量

在这种情况下,您对应用程序的请求很少,因此连接池中的所有连接很可能会失效,并且应用程序通过失效连接发出的第一个请求将导致错误。 (取决于您使用的 MySQL 驱动程序,该错误可能解释接收到的最后一个成功数据包超出了数据库的 wait_timeout 设置)。所以你的连接池策略是防止死连接被退回。以下两个选项对于低流量网站几乎没有副作用。

在终止连接之前等待更长的时间 - 您可以通过在 MySQL 配置中更改 wait_timeout 的值来做到这一点。在 MYSQL 工作台中,您可以在管理员 > 配置文件 > 网络下轻松找到该设置。对于流量很大的站点,通常不建议这样做,因为它可能导致池总是被填满 大量空闲连接。但请记住,这是低流量 场景。

测试每个连接 - 您可以通过设置 testOnBorrow = truevalidationQuery= "SELECT 1" 来做到这一点。性能呢?在这种情况下,您的流量很低。测试从池返回的每个连接都不是问题。这意味着一个额外的查询将被添加到您在单个连接上执行的每个 MySQL 事务中。在低流量网站上,这真的是您担心的事情吗?您的连接因为没有被使用而在池中死掉的问题是您的主要关注点。

中等流量

定期检查所有连接 - 如果您不想在每次使用时都测试每个连接,或者延长等待超时, 然后您可以定期测试所有默认连接或 您选择的自定义查询。例如设置validationQuery = "SELECT 1"testWhileIdle = "true"timeBetweenEvictionRunsMillis = "3600" 或您想要的任何间隔。对于非常低的流量,这是 绝对需要更多的工作。想想看。如果你有 30 池中的连接,并且在 1 小时内只有 4 个被调用,那么您可以使用之前的 testOnBorrow 方法轻松检查每个请求的所有 4 个连接,而性能影响很小。但是,如果您改为使用“每小时检查一次”的方法,那么您会发出 30 个请求来检查所有连接,仅 使用了 4 个。

高流量

尽快终止空闲连接 - 这种情况让每个人都说你不应该延长 wait_timeout 并且你 不应该测试每个连接。它不是适合所有情况的模型。当您有大量流量时 池中的每个连接都将被利用,您的实际问题 将增加可用连接的数量,同时 实际上缩短了wait_time 的长度,这样你就不会结束 数据库上有很多空闲连接。下面是一个小伙子的例子,他说他每天有多达 10,000 个空闲连接用于繁忙的站点,所以他想降低 wait_timeout Lowering the wait_timeout for busy site

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 Pool

【讨论】:

亲爱的乌斯曼,感谢您的回复。如果您可以使用 tomcat 池而不是 c3po 在可能的 jndi 资源中翻译上述场景,我将不胜感激。 最后我只是添加了示例配置。在低流量、中流量和高流量的每个部分中,我都添加了对 Tomcat 池特定字段的描述,您必须针对 JNDI 进行更改。如果您需要更多说明,请告诉我。 要添加到我上面的评论中,他们是一个链接,详细介绍了我在最底部修改的每个字段。

以上是关于tomcat 7.0.42 pooling, hibernate 4.2, mysql 坚如磐石的自动重新连接解决方​​案的主要内容,如果未能解决你的问题,请参考以下文章

Worklight 6.1,Tomcat 7.0.42 上的 SQL 适配器 (Oracle 11g) JNDI 错误

nginx+tomcat负载均衡策略

在 Apache Tomcat 7.0.42 及更高版本上部署 Mojarra 2.1.x 和 2.2 会导致 java.lang.UnsupportedOperationException

在 Eclipse 中指定了未知版本的 Tomcat

24生产预警项目平台之Tomcat的支持log4j,日志输出为json格式

Apache2.2 Tomcat7 集群 session共享 [windows]