感受在介紹以前有必要闡述一下鏈接池的幾個概念,有助於後邊一些文字的理解。
最原始的數據庫使用就是打開一個鏈接並進行使用,使用事後必定要關閉鏈接釋放資源。因爲頻繁的打開和關閉鏈接對jvm包括數據庫
都有必定的資源負荷,尤爲應用壓力較大時資源佔用比較多容易產生性能問題。由此使用鏈接池的做用就顯現出來,他的原理其實不復雜:
先打開必定數量的數據庫鏈接,當使用的時候分配給調用者,調用完畢後返回給鏈接池,注意返回給鏈接池後這些鏈接並不會關閉,而是
準備給下一個調用者進行分配。由此能夠看出鏈接池節省了大量的數據庫鏈接打開和關閉的動做,對系統性能提高的益處不言而喻。
幾個概念:
最小鏈接--應用啓動後隨即打開的鏈接數以及後續最小維持的鏈接數。
最大鏈接數--應用可以使用的最多的鏈接數
鏈接增加數--應用每次新打開的鏈接個數
舉個例子說明鏈接池的運做:
假設設置了最小和最大的鏈接爲10,20,那麼應用一旦啓動則首先打開10個數據庫鏈接,但注意此時數據庫鏈接池的正在使用數字爲0--由於你並無使用這些鏈接,而空閒的數量則是10。而後你開始登陸,假設登陸代碼使用了一個鏈接進行查詢,那麼此時數據庫鏈接池的正在使用數字爲一、空閒數爲9,這並不須要從數據庫打開鏈接--由於鏈接池已經準備好了10個給你留着呢。登陸結束了,當前鏈接池的鏈接數量是多少?固然是0,由於那個鏈接隨着事務的結束已經返還給鏈接池了。而後同時有11我的在同一秒進行登陸,會發生什麼:鏈接池從數據庫新申請(打開)了一個鏈接,連同另外的10個一併送出,這個瞬間鏈接池的使用數是11個,不過不要緊正常狀況下過一下子又會變成0。若是同時有21我的登陸呢?那第21我的就只能等前面的某我的登陸完畢後釋放鏈接給他。這時鏈接池開啓了20個數據庫鏈接--雖然極可能正在使用數量的已經降爲0,那麼20個鏈接會一直保持嗎?固然不,鏈接池會在必定時間內關閉必定量的鏈接還給數據庫,在這個例子裏數字是20-10=10,由於只須要保持最小鏈接數就行了,而這個時間週期也是鏈接池裏配置的。
好了,基本概念說完了,言歸正傳進行比較了。
首先說明的一點,爲了應用便於移植以及可配置的角度,建議仍是使用jndi統一進行鏈接池的配置。怎麼配置其實網上都有不少例子,
這裏簡單舉個例子(使用spring框架):
首先在應用的上下文定義中配置jndi名稱,如一個resource.xml文件,裏邊的寫法
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>jdbc/myapp</value></property>
</bean>
注意dataSource這個bean在dao層(hibernate或jdbc)的配置文件裏須要做爲dataSource名稱的屬性配置到全部bean中
其中「jdbc/myds」這個就是jndi名稱了,下一步就是在應用服務器鏈接池裏進行數據庫鏈接以及對應的jndi配置了
一 開源數據鏈接池
1 dbcp
dbcp多是使用最多的開源鏈接池,緣由大概是由於配置方便,並且不少開源和tomcat應用例子都是使用的這個鏈接池吧。
這個鏈接池能夠設置最大和最小鏈接,鏈接等待時間等,基本功能都有。這個鏈接池的配置參見附件壓縮包中的:dbcp.xml
使用評價:在具體項目應用中,發現此鏈接池的持續運行的穩定性仍是能夠,不過速度稍慢,在大併發量的壓力下穩定性
有所降低,此外不提供鏈接池監控
2 c3p0
c3p0是另一個開源的鏈接池,在業界也是比較有名的,這個鏈接池能夠設置最大和最小鏈接,鏈接等待時間等,基本功能都有。
這個鏈接池的配置參見附件壓縮包中的:c3p0.xml。
使用評價:在具體項目應用中,發現此鏈接池的持續運行的穩定性至關不錯,在大併發量的壓力下穩定性也有必定保證,
此外不提供鏈接池監控。
3 proxool
proxool這個鏈接池可能用到的人比較少,但也有必定知名度,這個鏈接池能夠設置最大和最小鏈接,鏈接等待時間等,基本功能都有。
這個鏈接池的配置參見附件壓縮包中的:proxool.xml。
使用評價:在具體項目應用中,發現此鏈接池的持續運行的穩定性有必定問題,有一個須要長時間跑批的任務場景任務,一樣的代碼
在另外2個開源鏈接池中成功結束,但在proxool中出現異常退出。
可是proxool有一個優點--鏈接池監控,這是個很誘人的東西,大概的配置方式就是在web.xml中添加以下定義:
<servlet>
<servlet-name>admin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>admin</servlet-name>
<url-pattern>/admin</url-pattern>
</servlet-mapping>
並在應用啓動後訪問:http://localhost:8080/myapp/admin這個url便可監控
不過proxool自己的包在監測使用中會有編碼問題,附件中有一個
解決此問題的包,參見附件壓縮包中的:proxool-0.9.0RC3.jar。另外須要jdk1.5以上的環境。
總結時刻:
綜上所述,這幾種開源鏈接池各有優劣,推薦使用c3p0,經檢驗這種鏈接池性能穩定,承壓能力強。而proxool儘管有明顯的性能問題,
但因爲它具有監控功能,所以建議在開發測試時使用,有助於肯定是否有鏈接沒有被關掉,能夠排除一些代碼的性能問題。
二 商業中間件鏈接池
上面列舉了幾種開源的鏈接池,其實能夠確定的說,若是條件容許使用weblogic和websphere等中間件,那麼不要猶豫,必定要
使用這些商業級別的中間件所自帶的數據庫鏈接池,他們的性能以及調配和開源的不在一個量級,舉個例子,曾經有一個項目,數據量比較大,一樣的代碼應用,在3種開源的鏈接池裏都多少出現過系統異常,而weblogic和websphere的鏈接池則正常運行,固然後來發現代碼有必定瑕疵,但也側面說明了商業鏈接池的強大。
1 weblogic的鏈接池
weblogic 8 是一個讓人使用起來很輕鬆方便的應用服務器軟件,可是到了9簡直就是折磨,不知道是bea是怎麼想的,oracle收購了bea之後出了10,比9強很多,可是最喜歡的仍是8。。。
題外話不說了,就以8.1版本介紹一下他的數據庫鏈接池(其實10的配置也差很少)
首先是鏈接池的基本設置,這個不講了,網上有不少教程。而後進入Data Sources菜單配置數據源裏邊的JNDI Name,要和以前在應用配置中的一致:jdbc/myapp。
而後是鏈接池一些具體項目的配置,包括設置最小(Initial Capacity),最大( Maximum Capacity)鏈接,以及
每次鏈接增長時須要一次性增長多少鏈接(Capacity Increment)。Allow Shrinking(是否把不用的鏈接退還數據庫以保持最小鏈接數--這個就能夠參見以前的鏈接池闡述的例子進行理解了)。
另外還有幾個有意思的選項Test Reserved Connections:對取得的鏈接進行測試,Test Released Connections:對釋放的鏈接進行測試。有人會問了,這個有什麼用啊?
不知道你們在項目中有沒有遇到java報鏈接失效的異常,反正我碰到過,只有在系統壓力大的時候纔出現。而有了這個選項就不用擔憂這個問題了--由於鏈接池已經幫你測試了,一旦檢查到鏈接是無效的他會廢棄掉還給數據庫,只給你有效的。不過這個鏈接失效的異常其實多半是應用的不嚴謹形成的,咱們更因該關心應代碼的問題--但起碼weblogic想到幫你彌補一下,是否是很貼心:)
另一個重要功能固然是鏈接池監控:monitor選項卡里能夠看到使用狀況,有人又要問了,沒有什麼指標啊,別忘了custom view這個功能連接哦:)
有如下指標:當前鏈接數、曾經達到的峯值、可使用的鏈接數、等待的鏈接數、從數據庫打開的鏈接數、曾經關閉的鏈接數。。。其中前3項是我最關注的
使用評價:在具體項目應用中,此鏈接池的持續運行的穩定性很強,在大併發量的壓力下性能也至關優秀,另外在一些異常狀況下鏈接池裏的鏈接也可以及時釋放。
鏈接池監控一目瞭然,及時到位。
2 websphere的鏈接池
仍是先來段題外話:記得有人說過,websphere只有版本6之後纔算是websphere,我的很贊同。websphere 5以及之前的版本。。。仍是忘了吧。
其實websphere的鏈接池秉承ibm一向的風格:功能強大,使用複雜:)
進入控制檯使用「JDBC提供程序」功能菜單進行鏈接池的基本配置,一路下來,不一樣的數據庫配置方式不盡相同,最奇怪的是還要單獨手工加上user和password參數,若是沒有
資料指導的話還真是摸不着頭腦。這些基本設置仍是網上找吧不少的。鏈接池設置完還須要設置數據源,jndi名字同樣與以前的對應:jdbc/myapp
高級設置包括初始化鏈接數,最大鏈接,鏈接有效性檢查,不使用超時。。其實這些都和weblogic中的鏈接池配置大體同樣。
鏈接池監控:使用運行監控菜單,裏邊會有一個監控項目選擇,選jdbc監控便可,可惡的是一開始彈出什麼服務器操做系統須要安裝什麼圖形化控件,選擇是那麼就得去找到控件在操做系統(linux)下安裝,而後不少的依賴組件都沒有。。。搞了半天才發現選擇否,監控數據以及圖形同樣能出來嘛,真是要怒了。
雖然通過一番波折可是監控的內容仍是很強大的,就鏈接池來講同樣包括當前鏈接數、曾經達到的峯值、可使用的鏈接數、從數據庫打開的鏈接數、曾經關閉的鏈接數。。。其中前3項是我最關注的,比較奇怪的現象是應用剛啓動的時候已開啓的鏈接數量居然沒有達到初始定義的鏈接數量,不清楚websphere是怎麼個計算機制。
另外在壓力大的時候可以使用的鏈接數會是負數,當時很奇怪,想一想也瞭然了,那個負數確定是排隊等待的數量了
使用評價:在具體項目應用中,此鏈接池的持續運行的穩定性至關強,在大併發量的壓力下性能也足夠優秀,另外在一些異常狀況下鏈接池裏的鏈接可以及時釋放,
鏈接池監控配置有些複雜,可是配置好後各項指標一目瞭然而且有圖形顯示
總結時刻:
這兩種商業級別的鏈接池都給我留下深入印象,功能強大,使用穩定,性能優秀,監控到位。能夠說難分伯仲,相對而言weblogic的鏈接池使用配置和監控配置更簡單明瞭,而websphere的更復雜但選項功能也更多一些。其實這正是對兩種應用服務器的使用印象的直接反映,固然整體比較2種應用服務器應該又是另外一個話題了,也許在下一期的內容裏。。。
比較了多種鏈接池的優劣,下面這個話題可能和比較自己沒有直接關係,但我的認爲應該是更有價值的一些經驗分享吧,那就是---這麼多指標配置,那些最大和最小鏈接數以及其餘一些必要的配置指標,在一個正式的生產項目中到底應該配置什麼值呢?
其實這個值首先仍是要根據具體的項目狀況、數據規模以及併發數來制定的(儘管像是套話,可是咱們研發人員嚴謹的做風仍是必要的:)。具體而言在中型偏小型的項目--給個數值把,用戶數300到3000,數據量100萬到1億---中,建議weblogic設置爲最大和最小都是200,websphere最小200最大300,前提是2者設置的最小內存要在1G以上,固然若是條件容許內存越大越好,不過32位機內存1.5G的限制是必定的(64位嘛我願意設個4G內存過來,速度提高的感受很爽啊)。這個數字出來之後相信會有很多問題要拋過來,我一一談一下本身的體驗和想法吧
1 爲何是200或300而不是更高?
回答: 再分配多了效果也不大了,一個是應用服務器維持這個鏈接數須要內存支持,剛纔說了32位的機器只能支持到1.5G,而且維護大量的鏈接進行分配使用對cpu也是一個不小的負荷,所以不宜太大。
2 爲何不小一點?
回答: 若是過小,那麼在上述規模項目的併發量以及數據量上來之後會形成排隊現象,系統會變慢,數據庫鏈接會常常打開和關閉,性能上有壓力,用戶體驗也很差。
3 爲何weblogic最小最大都同樣,而websphere不同
回答: 其實和分配內存的最小最大值的狀況同樣,通常都推薦2個值應該一致,都放在內存裏就行了嘛。可是ibm官方推薦2個值要有區別---官方說法仍是要聽的
4 其餘開源鏈接池的分配方案還沒說呢?
回答: 開源的我的認爲到100就能夠了,再高他也不會太穩定,固然1G的最小內存是必定要給tomcat分的
5 還有其餘的指標嗎?
回答: 固然還有一些,但我的認爲剩下的具體狀況具體分析了不在這裏一一列舉了,你們有興趣能夠和我討論分享一下。
林林總總說了很多但願對你們有幫助,這些比較分析和數據都具有實際應用支撐。java
last:mysql
Druid數據庫鏈接池使用:linux
阿里巴巴推出的國產數據庫鏈接池,據網上測試對比,比目前的DBCP或C3P0數據庫鏈接池性能更好git
簡單使用介紹github
Druid與其餘數據庫鏈接池使用方法基本同樣(與DBCP很是類似),將數據庫的鏈接信息所有配置給DataSource對象web
下面給出2種配置方法實例:spring
1. 純Java代碼建立sql
dataSource = new DruidDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUsername("root");dataSource.setPassword("11111111");dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/jspdemo");dataSource.setInitialSize(5);dataSource.setMinIdle(1);dataSource.setMaxActive(10); // 啓用監控統計功能 dataSource.setFilters("stat");// for mysql dataSource.setPoolPreparedStatements(false);
2. 基於Spring建立數據庫
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!-- 基本屬性 url、user、password --> <property name="url" value="${jdbc_url}" /> <property name="username" value="${jdbc_user}" /> <property name="password" value="${jdbc_password}" /> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="1" /> <property name="minIdle" value="1" /> <property name="maxActive" value="20" /> <!-- 配置獲取鏈接等待超時的時間 --> <property name="maxWait" value="60000" /> <!-- 配置間隔多久才進行一次檢測,檢測須要關閉的空閒鏈接,單位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一個鏈接在池中最小生存的時間,單位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="300000" /> <property name="validationQuery" value="SELECT 'x'" /> <property name="testWhileIdle" value="true" /> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <!-- 打開PSCache,而且指定每一個鏈接上PSCache的大小 --> <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> <!-- 配置監控統計攔截的filters --> <property name="filters" value="stat" /> </bean>
啓用Web監控統計功能須要在Web應用的web.xml中加入這個Servlet聲明tomcat
<servlet> <servlet-name>DruidStatView</servlet-name> <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DruidStatView</servlet-name> <url-pattern>/druid/*</url-pattern> <servlet-mapping>
經過 http://ip:port/druid/ 地址訪問便可
項目地址
https://github.com/AlibabaTech/druid/wiki
直接下載發佈版本便可,不必下載源碼從新編譯
其中的FAQ部分頗有參考價值