tomcat 7.0.42 pooling,hibernate 4.2,mysql rock solid autoreconnect解决方案

时间:2013-08-06 11:19:46

标签: mysql hibernate tomcat pooling

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

非常感谢,

此致

1 个答案:

答案 0 :(得分:21)

很好的问题。我用来解决这个问题。对于几乎每个问题,stackoverflow上最常见的答案是“它取决于......”。我不愿意这么说但是没有比调整你的连接池更有意义的地方。它实际上是一个供需游戏,您的连接请求是需求,供应是MySQL可用的连接数。这主要取决于您的主要关注点是阻止从池中返回过时的连接,还是您的关注是否确保MySQL没有因空闲连接而过载,因为您没有足够快地杀死它们。大多数人在中间某些地方撒谎。

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

低流量

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

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

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

中等流量

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

高流量

  • 杀死空闲连接 - 这种情况让每个人都说你不应该延长wait_timeout而你 不应该测试每个连接。对于每种情况,它都不是理想的模型。当你有大量的流量 将利用池中的每个连接和您的实际问题 将增加可用连接数 实际上缩短了wait_time的长度,所以你不会结束 DB上有很多空闲连接。这是一个小伙子的例子,谈论他如何每天为繁忙的网站提供多达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 Pool

的Tomcat池属性的文档