Spring+SpringMVC+MyBatis+easyUI整合優(yōu)化篇(九)數(shù)據(jù)層優(yōu)化-jdbc連接池簡述、druid簡介

日常啰嗦

終于回到既定軌道上了,這一篇講講數(shù)據(jù)庫連接池的相關(guān)知識,線程池以后有機會再結(jié)合項目單獨寫篇文章(自己給自己挖坑,不知道什么時候能填上),從這一篇文章開始到本階段結(jié)束的文章都會圍繞數(shù)據(jù)庫和dao層的優(yōu)化去寫,本篇是一個開始。本文會介紹連接池技術(shù)并對比目前比較流行的java連接池技術(shù),之后,會把druid整合到項目中來,將技術(shù)方案落地,實際整合到項目中,讓技術(shù)能為我所用。

使用連接池的原因

jdbc的demo

//第一步,注冊驅(qū)動程序  
//com.MySQL.jdbc.Driver  
Class.forName("數(shù)據(jù)庫驅(qū)動的完整類名");
//第二步,獲取一個數(shù)據(jù)庫的連接  
Connection conn = DriverManager.getConnection("數(shù)據(jù)庫地址","用戶名","密碼");    
//第三步,創(chuàng)建一個會話  
Statement stmt=conn.createStatement();   
//第四步,執(zhí)行SQL語句  
stmt.executeUpdate("SQL語句");  
//或者查詢記錄  
ResultSet rs = stmt.executeQuery("查詢記錄的SQL語句");  
//第五步,對查詢的結(jié)果進(jìn)行處理  
while(rs.next()){  
//操作  
}  
//第六步,關(guān)閉連接  
rs.close();  
stmt.close();  
conn.close();

對上面幾行代碼,大家不會陌生,這可能是我們初學(xué)jdbc連接時最熟悉的代碼了,雖然現(xiàn)在可能用到了一些數(shù)據(jù)層ORM框架,但是底層實現(xiàn)依然如同上面代碼一樣,只是做了一些封裝而已。這種方式也有一些不足,在與mysql進(jìn)行數(shù)據(jù)交互時每次都需要新建connection資源,用完后關(guān)閉掉Connection資源,這種做法是非常浪費資源的,如果抬杠的話,可能有人會說,我就喜歡這種方式,我服務(wù)器配置足夠好,我一點都不擔(dān)心什么資源不資源,那你牛逼。

浪費資源這種說法是相對而言的,如果在小型項目中或者項目與數(shù)據(jù)庫的交互不那么頻繁的話,數(shù)據(jù)庫連接的創(chuàng)建與關(guān)閉也不見得會把資源浪費多少,亦或者在項目啟動時期,我們可能只考慮功能實現(xiàn),就直接copy一份現(xiàn)成的數(shù)據(jù)庫集成代碼過來用,這種做法都是很正常的現(xiàn)象,本階段的內(nèi)容主要是項目優(yōu)化,那么關(guān)注點肯定就不是項目初始時期,也不去討論硬件配置有多好,而是針對目前代碼中的不足進(jìn)行優(yōu)化,找到一個相對較好的優(yōu)化方案,并落實到項目中去,今天我們講的優(yōu)化方案就是使用連接池技術(shù)代替目前與數(shù)據(jù)庫的交互方式。

為什么在連接數(shù)據(jù)庫時要使用連接池?
數(shù)據(jù)庫連接是一種關(guān)鍵的有限的昂貴的資源,一個數(shù)據(jù)庫連接對象均對應(yīng)一個物理數(shù)據(jù)庫連接,每次操作都打開一個物理連接,使用完都關(guān)閉連接,這樣造成系統(tǒng)的性能低下。

數(shù)據(jù)庫連接池的解決方案是在應(yīng)用程序啟動時建立足夠的數(shù)據(jù)庫連接,并將這些連接組成一個連接池,簡單的說,就是在一個"池"里放了好多半成品的數(shù)據(jù)庫連接對象,由應(yīng)用程序動態(tài)地對池中的連接進(jìn)行申請、使用和釋放等操作。

連接池技術(shù)盡可能多地重用了消耗內(nèi)存地資源,大大節(jié)省了內(nèi)存,提高了服務(wù)器的服務(wù)效率,減少了程序與數(shù)據(jù)庫交互時的部分開銷,顯著的改善應(yīng)用程序的性能,通過使用連接池,提高了程序運行效率,同時,我們可以通過其自身的管理機制來監(jiān)視數(shù)據(jù)庫連接的數(shù)量、使用情況等。

連接池的工作原理

連接池技術(shù)的核心思想是連接復(fù)用(也是我們在前一篇文章中提到的資源重用),通過建立一個數(shù)據(jù)庫連接池以及一套連接使用、分配和管理策略,使得該連接池中的連接可以得到高效、安全的復(fù)用,避免了數(shù)據(jù)庫連接頻繁建立、關(guān)閉的開銷。

連接池的工作原理主要由三部分組成,分別為連接池的建立、連接池中連接的使用管理、連接池的關(guān)閉:

  • 第一、連接池的建立。一般在系統(tǒng)初始化時,連接池會根據(jù)系統(tǒng)配置建立,并在池中創(chuàng)建了幾個連接對象,以便使用時能從連接池中獲取。連接池中的連接不能隨意創(chuàng)建和關(guān)閉,這樣避免了連接隨意建立和關(guān)閉造成的系統(tǒng)開銷。Java中提供了很多容器類可以方便的構(gòu)建連接池,例如Vector、Stack等。

  • 第二、連接池的管理。連接池管理策略是連接池機制的核心,連接池內(nèi)連接的分配和釋放對系統(tǒng)的性能有很大的影響。其管理策略是:

    • 當(dāng)客戶請求數(shù)據(jù)庫連接時,首先查看連接池中是否有空閑連接,如果存在空閑連接,則將連接分配給客戶使用;

    • 如果沒有空閑連接,則查看當(dāng)前所開的連接數(shù)是否已經(jīng)達(dá)到最大連接數(shù),如果沒達(dá)到就重新創(chuàng)建一個連接給請求的客戶;

    • 如果達(dá)到就按設(shè)定的最大等待時間進(jìn)行等待,如果超出最大等待時間,則拋出異常給客戶。

    • 當(dāng)客戶釋放數(shù)據(jù)庫連接時,先判斷該連接的引用次數(shù)是否超過了規(guī)定值,如果超過就從連接池中刪除該連接,否則保留為其他客戶服務(wù)。

      該策略保證了數(shù)據(jù)庫連接的有效復(fù)用,避免頻繁的建立、釋放連接所帶來的系統(tǒng)資源開銷。

  • 第三、連接池的關(guān)閉。當(dāng)應(yīng)用程序退出時,關(guān)閉連接池中所有的連接,釋放連接池相關(guān)的資源,該過程正好與創(chuàng)建相反。

連接池的優(yōu)點及流行的連接池技術(shù)

對于連接池的優(yōu)點,通過前文描述,我們也能得出以下結(jié)論:

  • 減少連接創(chuàng)建時間。連接池中的連接是已準(zhǔn)備好的、可重復(fù)使用的,獲取后可以直接訪問數(shù)據(jù)庫,因此減少了連接創(chuàng)建的次數(shù)和時間。
  • 簡化的編程模式。當(dāng)使用連接池時,每一個單獨的線程能夠像創(chuàng)建一個自己的JDBC連接一樣操作,允許用戶直接使用JDBC編程技術(shù)。
  • 控制資源的使用。如果不使用連接池,每次訪問數(shù)據(jù)庫都需要創(chuàng)建一個連接,這樣系統(tǒng)的穩(wěn)定性受系統(tǒng)連接需求影響很大,很容易產(chǎn)生資源浪費和高負(fù)載異常。連接池能夠使性能最大化,將資源利用控制在一定的水平之下。連接池能控制池中的連接數(shù)量,增強了系統(tǒng)在大流量沖擊下的穩(wěn)定性。

流行的Java連接池:

  • C3P0是一個開放源代碼的JDBC連接池,它在lib目錄中與Hibernate一起發(fā)布,包括了實現(xiàn)jdbc3和jdbc2擴(kuò)展規(guī)范說明的Connection 和Statement 池的DataSources 對象。

  • DBCP (Database Connection Pool)是一個依賴Jakarta commons-pool對象池機制的數(shù)據(jù)庫連接池,Tomcat的數(shù)據(jù)源使用的就是DBCP。目前 DBCP 有兩個版本分別是 1.3 和 1.4。1.3 版本對應(yīng)的是 JDK 1.4-1.5 和 JDBC 3,而1.4 版本對應(yīng) JDK 1.6 和 JDBC 4。因此在選擇版本的時候要看看你用的是什么 JDK 版本了,功能上倒是沒有什么區(qū)別。

  • Proxool是一個Java SQL Driver驅(qū)動程序,提供了對你選擇的其它類型的驅(qū)動程序的連接池封裝。可以非常簡單的移植到現(xiàn)存的代碼中。完全可配置。快速,成熟,健壯。可以透明地為你現(xiàn)存的JDBC驅(qū)動程序增加連接池功能

  • Druid是阿里開源的一個數(shù)據(jù)庫連接池技術(shù),號稱是目前最好的數(shù)據(jù)庫連接池,在功能、性能、擴(kuò)展性方面,都超過其他數(shù)據(jù)庫連接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已經(jīng)在阿里巴巴部署了超過600個應(yīng)用,經(jīng)過一年多生產(chǎn)環(huán)境大規(guī)模部署的嚴(yán)苛考驗。

對比下來,最終選擇了Druid連接池,接下來也會將Druid技術(shù)整合到目前的項目中去,C3P0和DBCP都用過,也碰到一些問題,總體來說,功能中規(guī)中矩,比直接操作jdbc方式要好的多,但是對比與Druid的話就有些不足了,因為Druid是在目前市面上流行的連接池技術(shù)的基礎(chǔ)上開發(fā)出來的,你有的Druid有,你沒有的Druid也能提供,Druid不僅僅是一個高效可管理的數(shù)據(jù)庫連接池,它還有一套基于Filter-Chain模式的插件體系,也內(nèi)置SQLParser功能,同時還能監(jiān)控數(shù)據(jù)庫訪問性能,可以作為監(jiān)控來使用,總結(jié)起來就是高效、功能強大、可擴(kuò)展性好。

總結(jié):目前的問題及解決方案

目前ssm-demo項目中與mysql服務(wù)器的交互使用的是Spring自帶的一個工具類,DriverManagerDataSource,配置文件如下:

<!-- 配置數(shù)據(jù)源 -->
    <bean id="dataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url"
                  value="jdbc:mysql://127.0.0.1:3306/ssm_db?useUnicode=true&amp;characterEncoding=UTF-8  "/>
       <property name="username" value="root"/>
        <property name="password" value="admin"/>
    </bean>

DriverManagerDataSource建立連接的作法是只要有連接就新建一個connection,根本沒有連接池的作用,也就是說文章前面所提到的資源消耗的弊端還是存在的,但是我們覺察不出來,感覺項目也挺正常的。這是因為目前網(wǎng)站的訪問量較小,與mysql數(shù)據(jù)庫的交互不頻繁,由于訪問量小,對后端的請求就少,因此mysql查詢就少,壓力也不會大,項目體量及訪問總量都很小,就更別提數(shù)據(jù)庫的QPS了,根本不值一提,也就是說現(xiàn)有的網(wǎng)站形勢下,根本不會對mysql數(shù)據(jù)庫產(chǎn)生任何的壓力,根本不會有死鎖的產(chǎn)生,根本不會有事務(wù)鎖的產(chǎn)生,根本不會有數(shù)據(jù)庫資源耗盡情況的產(chǎn)生,也根本不會有數(shù)據(jù)庫服務(wù)器崩掉的產(chǎn)生.....

但是如果網(wǎng)站的訪問量大了起來,功能豐富了起來,用戶訪問量增長了起來,是目前的10000倍、100000倍甚至更大的情況下,各種問題就隨之而來了,當(dāng)然,這么多問題出現(xiàn)了,我們是不是修改了數(shù)據(jù)連接池就好了?肯定不是,數(shù)據(jù)庫連接池僅僅解決了數(shù)據(jù)層的部分問題,對性能有一部分的提升,它不能解決掉網(wǎng)站演進(jìn)過程中的各種問題,別想太多,因為過程中會出現(xiàn)各種各樣的問題,項目也會暴露出各個方面的不足,前端、后端、運維、DBA、架構(gòu)....等等維度都有可能出現(xiàn)問題,需要不同的方案和不同的技術(shù)來優(yōu)化,不要想著一勞永逸。

OK,可能有點扯遠(yuǎn)了,還是說回到連接池,下一篇文章會介紹阿里的Druid連接池技術(shù)并將其整合到項目中,待續(xù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內(nèi)容