我先說說數據庫連接
數據庫大家都不陌生,從名字就能看出來它是「存放數據的倉庫」,那我們怎么去「倉庫」取東西呢?當然需要鑰匙啦!這就是我們的數據庫用戶名、密碼了,然后我們就可以打開門去任意的存取東西了。這個時候,我們與數據庫之間的連接就是「數據庫連接」。
這個時候問題就來了,當我們僅僅只需要去取一個東西的時候,我們取完東西隨手關上門,然后拔出鑰匙,這完全是再正常不過的流程了,完全沒毛病,但是,我們大部分時間是需要一件件的把倉庫中的東西搬到外面停放的大卡車上,那這時候我們如果取一件東西把門鎖上,然后再打開門取一件再次鎖上,這有沒有毛病?在我看來,這個邏輯完全正確,沒一點毛病,就是這樣必然會影響我們裝貨的效率嘛!正常人肯定會想到我們不鎖門不就行了,等這批貨裝完了,我們再鎖上門。這可以阿,但是,會不會有安全及其他問題?還有這時候你是否允許別人從你打開的門進入倉庫搬東西?
如果,這時候我們招聘了一個「倉庫管理員」幫忙我們管理會怎樣?當然完美啦,他會在你進入倉庫時給你「授權令」進入,然后可能還會在你出來的時候檢查下你搬的貨物是否正確,並做下記錄以及報表分析,然后你完成時把你的「授權令」還給他,另外一個人進入當然也是這樣的,也並不會影響到你的工作,你倆當然可以同時搬東西,倉庫管理員並不會在你結束的時候鎖上門。
何為數據庫連接池
其實上面的「倉庫管理員」我就認為是我們程序世界的數據庫連接池。因為他手里拿着大把的進入倉庫的令牌,他給你一個你就能進去,出來后你還給他,他再接着可以給下一個人,這個時候我們倉庫門是一直打開的狀態,省去了大把我們開鎖、開門、關門、鎖門的操作,完全交由一個專業人士管理,更神奇的是他還能記錄你的一系列操作。
看概念:
數據庫連接池負責分配、管理和釋放數據庫連接,它允許應用程序重復使用一個現有的數據庫連接,而不是再重新建立一個;釋放空閑時間超過最大空閑時間的數據庫連接來避免因為沒有釋放數據庫連接而引起的數據庫連接遺漏。這項技術能明顯提高對數據庫操作的性能。
摘自百度百科
在大部分 .Net 開發人心目中,好像並沒有數據庫連接池的概念,只有數據庫連接,然后用完要記得close
和用using
,在 Java 中有太多的開源的數據庫連接池,而且好像一個吹的比一個厲害。我其實告訴你,其實在 .Net 中 ADO.Net 已經幫我們實現了數據庫連接池,我們並不需要什么配置,用就是了,但 Java 不一樣,需要我們自己選擇合適的數據庫連接池。下面我說說項目中為什么選擇了阿里的 Druid 數據庫連接池。
為監控而生的數據庫連接池
這是它在 GitHub 上的描述,它有四千多的 Star , 這些並不重要,其實他的監控功能做的很不錯,對開發完成后我們代碼優化提供了大量的參考,至少在數據庫連接層面的提升是明顯可見的。我們曾經把一個耗時半分鍾的查詢優化到毫秒級別,當然這並不是全靠優化數據庫查詢,但它對調優有重要幫助。
網上有很多各個比較常用的連接池的對比,如 c3p0 ,Proxool ,Druid ,Tomcat Jdbc Pool 等等這些,你可以搜到詳細的對比,我這里不再討論,我提供一個 連接池c3p0 ,Proxool ,Druid ,Tomcat Jdbc Pool對比測試,可以參考。下面是官方的功能對比:
這些內容你都可以在 GitHub(https://github.com/alibaba/druid/)上找到。
配置起來也很簡單
一、下載druid-1.0.9.jar
導入到項目
這一步你就去下載就行了,地址:http://central.maven.org/maven2/com/alibaba/druid/1.0.9/druid-1.0.9.jar
二、applicationContext.xml
文件配置數據庫連接
這好像和其他數據庫連接池沒多少區別,除了幾個參數不同而已,我貼出我的配置
<!--master 配置數據源 -->
<bean id="masterDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://127.0.0.1:3306/springdemo?useUnicode=true&characterEncoding=UTF-8</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>123456</value>
</property>
<!-- 通過別名的方式配置擴展插件,常用的插件有:監控統計用的filter:stat 日志用的filter:log4j 防御sql注入的filter:wall -->
<property name="filters" value="stat,log4j" />
<!-- 最大並發連接數 -->
<property name="maxActive" value="30" />
<!-- 初始化連接數量 -->
<property name="initialSize" value="5" />
<!-- 配置獲取連接等待超時的時間 -->
<property name="maxWait" value="60000" />
<!-- 最小空閑連接數 -->
<property name="minIdle" value="5" />
<!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 -->
<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" />
<property name="poolPreparedStatements" value="false" />
<property name="maxOpenPreparedStatements" value="100" />
<!-- 打開removeAbandoned功能(連接泄漏監測,懷疑存在泄漏之后再打開) -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分鍾 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 關閉abanded連接時輸出錯誤日志 -->
<property name="logAbandoned" value="true" />
</bean>
上面的參數都可以根據自己的需要來調整。具體配置請訪問我的 GitHub 示例https://github.com/mafly/SpringDemo/blob/master/WebContent/WEB-INF/applicationContext.xml
三、web.xml
文件配置監控平台
<!-- 連接池 啟用Web監控統計功能 start-->
<filter>
<filter-name>DruidWebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>*.js,*mp3,*.swf,*.xls,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>DruidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<init-param>
<!-- 允許清空統計數據 -->
<param-name>resetEnable</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<!-- 用戶名 -->
<param-name>loginUsername</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<!-- 密碼 -->
<param-name>loginPassword</param-name>
<param-value>123456</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
<!-- 連接池 啟用Web監控統計功能 end-->
在文件中加入上面配置,就可以在項目地址后加druid
后訪問監控平台,看一下數據庫連接及 SQL 語句執行時間,當然登錄密碼什么的自己配置啦。登錄后界面:
總結一下
我這里當然就是拋磚引玉的簡單說了一下 Druid 數據庫連接池的基本配置,更多強大功能等待大家去體驗,在我們時間項目中,使用起來會比原來 c3p0 要爽,這里要感謝項目組中小慷同學的技術分享, Druid 的具體情況及各種配置大家都可以去 https://github.com/alibaba/druid/ 查看,文檔還是比較詳細的。
當然,我上面的配置大家也都可以訪問我 GitHub(改版了,你去看看)上的 Spring 示例項目查看:https://github.com/mafly/SpringDemo/。