2011-06-17 94 views
2

我在我的服務器上部署了spring/hibernate/mysql。由於有些日子我面臨的問題是我的應用程序似乎打開了很多與數據庫的連接。休眠/彈出:很多(數千)打開的連接數據庫

tcp6  0  0 ************:53547  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53595  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53645  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:34986  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53669  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53710  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53757  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53716  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53627  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53752  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53505  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53549  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:35185  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53604  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:35331  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53488  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:34938  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:34987  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53695  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:35380  ************:3306  TIME_WAIT 0   0   - 
tcp6  0  0 ************:53651  ************:3306  TIME_WAIT 0   0   - 

然而,在MySQL工作臺服務器運行狀況選項卡找我的MySQL數據庫的時候,它看起來一切都將被罰款:我從netstat的輸出,它看起來像這樣(IP地址混淆)服用此提示(見附件截圖)。

此外我的應用程序有正常的性能。

我們目前正在積極開發應用程序,但我們看不到任何影響此行爲的代碼更改。顯然肯定有變化,但它也可能是一個配置問題,或者其他什麼。

它可能是一個Hibernate連接池嗎?奇怪的是,所有的連接都在等待。

我很感謝所有的想法和提示!

編輯 - Hibernate配置(使用Spring)

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName"> 
     <value>com.mysql.jdbc.Driver</value> 
    </property> 
    <property name="url"> 
     <value>jdbc:mysql://************:3306/********</value> 
    </property> 
    <property name="username"> 
     <value>********</value> 
    </property> 
    <property name="password"> 
     <value>********</value> 
    </property> 
</bean> 

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
     <property name="dataSource"> 
      <ref bean="dataSource" /> 
     </property> 
     <property name="configLocation"> 
      <value>WEB-INF/hibernate.hbm.xml</value> 
     </property> 
     <property name="configurationClass"> 
      <value>org.hibernate.cfg.AnnotationConfiguration</value> 
     </property> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> 
       <prop key="hibernate.jdbc.batch_size">0</prop> 
       <prop key="hibernate.show_sql">false</prop> 
       <prop key="hibernate.bytecode.provider">cglib</prop> 
       <prop key="hibernate.hbm2ddl.auto">update</prop> 
      </props> 
     </property> 
     <property name="eventListeners"> 
      <map> 
       <entry key="save-update" value-ref="saveUpdateEventListener" /> 
      </map> 
     </property> 
    </bean> 

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 

SOLUTION:我現在結束了使用雄貓JNDI數據源和它最終的作品。只有11(!!)到DATABSE連接使用;)謝謝@Vineet雷諾

+0

Hibernate沒有我能想到的連接池。你有沒有使用c3p0? – Pace 2011-06-17 13:33:58

+0

有像c3p0這樣的開源連接池。如果不是這種情況,請檢查您明確獲取可能是連接泄漏源的連接的代碼塊。確保它們關閉。檢查您的數據源設置以更好地理解問題。如果是這種情況,通常會有一些配置參數幫助您捕獲連接泄漏。 – 2011-06-17 13:42:33

回答

3

Hibernate documentation介紹了連接池是如何建立在Hibernate中:

Hibernate will obtain and pool connections using java.sql.DriverManager if you set the following properties: 

Table 3.1. Hibernate JDBC Properties 

Property name      Purpose 
hibernate.connection.driver_class JDBC driver class 
hibernate.connection.url   JDBC URL 
hibernate.connection.username  database user 
hibernate.connection.password  database user password 
hibernate.connection.pool_size  maximum number of pooled connections 

,更重要的是:

Hibernate的自己的連接池 算法,但是,相當 基本。 它旨在幫助您開始使用 ,並且不打算在生產系統中使用 ,即使在性能測試中也使用 。

如果正在使用的文檔中描述的值,這將導致休眠管理池中沒有委託池管理到生產就緒的連接池實現這將是值得一試。

就netstat的輸出而言,連接的數量和打開它們的原因是決定你是否有問題的最重要的標準。通常,生產就緒的池實現將僅在必要時纔打開連接,並且還能夠縮小池大小。另外,如果沒有使用這種池管理器,連接可能會被丟棄。從處於TIME_WAIT狀態的連接數看來,服務器正在等待來自客戶端的流量;這可能是物理連接在不再需要之後不會被丟棄的情況。

儘管上述所有觀察結果都只有一個結果 - 使用比默認值更好的連接池實現,並且其性能特徵也很好理解。你會得到建議,使用c3p0BoneCP,從這裏的很多人。

更新

根據張貼的春天Hibernate的配置,看來a datasource is used to obtain connections for Hibernate。因此數據源後面的底層連接池的配置將被使用。

更新#2

更新的Spring應用程序上下文文件,使用Spring框架的DriverManagerDataSource。從文檔說明廣告逐字:

注:這個類不是一個實際的 連接池;它實際上並不是 池連接。它只是作爲 簡單替換成一個完整的 連接池,實現相同的 標準接口,但創建新的 連接在每個呼叫。

需要注意的重要一點是DriverManagerDataSource依賴於提供給它的屬性來創建連接。正如文檔中所述,它將使用DriverManager而不是JNDI綁定的DataSource來創建連接。這裏重要的一點是,DriverManager通常返回到數據庫的物理連接,與返回邏輯連接包裝的DataSource不同。它顯示(從netstat輸出)這些物理連接沒有被關閉。也許,Hibernate並沒有關閉連接;但那不太可能;您最好使用更好的連接池實現,該連接池實現可以配置爲擁有永不超過池大小的實際連接對象池。