2013-08-06 13 views
10

我讀過很多關於自動重新連接到hibernate session的問題的文章。其他人提到增加了mysql的wait_timeout(不是我最喜歡的),使用autoReconnect = true(不推薦),測試連接e.t.c.我目前正在嘗試一些選項,但我想問問是否有人使用tomcat的連接池(而不是休眠的c3po)的堅實解決方案。即使它們不是最佳的性能調整,我也正在尋找最具彈性的jndi設置。tomcat 7.0.42 pooling,hibernate 4.2,mysql rock solid autoreconnect解決方案

非常感謝你,

問候

回答

21

非常好的問題。我用這個問題來解決這個問題。對於幾乎所有問題,stackoverflow上最常見的答案是「它取決於......」。我討厭這麼說,但沒有比調整連接池更重要的地方。它確實是一種供求博弈,其中連接請求是需求,供應是MySQL可用的連接數量。這主要取決於您的主要擔心是否阻止從池中返回陳舊的連接,或者您的擔心是否確保MySQL不會因空閒連接而過載,因爲您不會以足夠快的速度查殺它們。大部分人在中間的某些地方都是鹼液。

如果你真的明白爲什麼有人會選擇任何一個連接池配置,那麼相信我你會停止搜索「Rocket Solid」設置,因爲你會知道這就像是對你的商店的商業計劃谷歌搜索;這完全取決於您獲得多少連接請求以及您願意提供多少個持續連接。下面我舉例說明你爲什麼要使用某些設置。我引用的變量必須在Context.xml文件的「Context」標記的「Resource」標記內進行更改。完整的配置示例可以在底部看到。

低流量的

在這種情況下,你有你的應用程序很少請求,以便有一個很好的機會,在你的連接池中的所有連接會過時,並通過應用程序中的第一個請求由一個陳舊的連接會造成一個錯誤。 (根據您使用錯誤的MySQL驅動程序,可能會解釋上次收到的成功數據包超出了數據庫的wait_timeout設置)。所以你的連接池策略是防止返回一個死連接。對於低流量站點,以下兩個選項幾乎沒有副作用。

  • 等待更長的時間殺死連接之前 - 你會在你的MySQL配置改變wait_timeout值做到這一點。在MYSQL工作臺中,您可以在Admnin> Configuration file> Networking下輕鬆找到該設置。對於有很多流量的站點,通常不推薦這樣做,因爲它可能導致池總是被大量的空閒連接填滿。但請記住,這是低流量 的情況。

  • 測試每個連接 - 您可以通過設置testOnBorrow = truevalidationQuery= "SELECT 1"來完成此操作。性能如何?在這種情況下你的流量很低。測試從池返回的每個連接都不是問題。所有這一切意味着您將在單個連接上執行的每個MySQL事務中添加一個額外的查詢。在低流量的網站上,這真的是你會擔心的事情嗎?您的連接因池未被使用而死亡的問題是您的主要焦點。

中等交通

  • 檢查所有連接定期 - 如果你不想每次使用時間來檢驗每個連接,或延長等待超時, 那麼你就可以使用您選擇的默認或自定義查詢定期測試所有連接。例如,設置爲validationQuery = "SELECT 1",testWhileIdle = "true"timeBetweenEvictionRunsMillis = "3600"或您想要的任何間隔。對於非常低的流量,這是絕對需要更多工作的 。想想看。如果連接池中有30 連接,並且在1小時內只有4個連接被呼叫,那麼您可以使用之前的testOnBorrow方法輕鬆檢查每個請求中的所有4個連接,而性能幾乎沒有影響。但是,如果您使用「每小時檢查一次」的方法,那麼只有使用了 4時,纔會發出30個請求來檢查所有連接。

高流量

  • 殺空閒連接遲早 - 這是一個人有每個人說你不應該延長WAIT_TIMEOUT,你 不應該測試每一個連接的情況。這不是每種情況下的模式理想。當你有顯着的流量 池中的每個連接將被利用,並且你的實際問題 將會增加可用連接的數量,而 實際上縮短了你的長度wait_time因此你不會結束 大量空閒連接D B。這裏是講一個小夥子的例子如何,他有多達一個繁忙的網站,所以他要降低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

+0

親愛的烏斯曼,謝謝你的回覆。我非常感謝,如果你可以在tomcat池中將可能的jndi資源翻譯成上述場景,而不是c3po。 – sygram

+0

最後我剛添加了示例配置。並且在低流量,中等流量和高流量的每個部分中,我添加了關於Tomcat池特定字段的說明,您必須在JNDI方面進行更改。讓我知道你是否需要更多的澄清。 –

+0

要添加到我的評論上面,他們是一個鏈接,詳細介紹了我在最底部修改的每個領域。 –