阿里開源Druid數(shù)據(jù)庫連接池使用

文章來源:https://www.relaxheart.cn/to/master/blog?uuid=76

前言


池(Pool)技術(shù)在一定程度上可以明顯優(yōu)化服務(wù)器應(yīng)用程序的性能,提高程序執(zhí)行效率和降低系統(tǒng)資源開銷。這里所說的池是一種廣義上的池愿卸,比如數(shù)據(jù)庫連接池贺喝、線程池辰如、內(nèi)存池怎栽、對(duì)象池等颊亮。其中剔宪,對(duì)象池可以看成保存對(duì)象的容器拂铡,在進(jìn)程初始化時(shí)創(chuàng)建一定數(shù)量的對(duì)象。需要時(shí)直接從池中取出一個(gè)空閑對(duì)象歼跟,用完后并不直接釋放掉對(duì)象和媳,而是再放到對(duì)象池中以方便下一次對(duì)象請(qǐng)求可以直接復(fù)用。其他幾種池的設(shè)計(jì)思想也是如此哈街,池技術(shù)的優(yōu)勢(shì)是留瞳,可以消除對(duì)象創(chuàng)建所帶來的延遲,從而提高系統(tǒng)的性能骚秦。

要了解Java連接池我們先要了解數(shù)據(jù)庫連接池(connection pool)的原理她倘,Java連接池正是數(shù)據(jù)庫連接池在Java上的應(yīng)用∽鞴浚——我們知道硬梁,對(duì)于共享資源,有一個(gè)很著名的設(shè)計(jì)模式:資源池(Resource Pool)胞得。

該模式正是為了解決資源的頻繁分配﹑釋放所造成的問題荧止。為解決上述問題,可以采用數(shù)據(jù)庫連接池技術(shù)阶剑。數(shù)據(jù)庫連接池的基本思想就是為數(shù)據(jù)庫連接建立一個(gè)“緩沖池”跃巡。預(yù)先在緩沖池中放入一定數(shù)量的連接,當(dāng)需要建立數(shù)據(jù)庫連接時(shí)牧愁,只需從“緩沖池”中取出一個(gè)素邪,使用完畢之后再放回去。我們可以通過設(shè)定連接池最大連接數(shù)來防止系統(tǒng)無盡的與數(shù)據(jù)庫連接猪半。更為重要的是我們可以通過連接池的管理機(jī)制監(jiān)視數(shù)據(jù)庫的連接的數(shù)量﹑使用情況兔朦,為系統(tǒng)開發(fā)﹑測(cè)試及性能調(diào)整提供依據(jù)。

由于自己只是儲(chǔ)備的限制磨确,知道的數(shù)據(jù)庫鏈接池只有JNDI沽甥、C3P0,DBCP,Druid這幾種,今天主要介紹Druid俐填,因?yàn)樵贒ruid的出現(xiàn)是為了替代C3P0安接、DBCP數(shù)據(jù)庫連接池(因?yàn)樗男阅芨?。

Druid介紹


Druid首先是一個(gè)數(shù)據(jù)庫連接池英融。Druid是目前最好的數(shù)據(jù)庫連接池盏檐,在功能、性能驶悟、擴(kuò)展性方面胡野,都超過其他數(shù)據(jù)庫連接池,包括DBCP痕鳍、C3P0硫豆、BoneCP、Proxool笼呆、JBoss DataSource熊响。

Druid已經(jīng)在阿里巴巴部署了超過上千個(gè)應(yīng)用,經(jīng)過一年多生產(chǎn)環(huán)境大規(guī)模部署的嚴(yán)苛考驗(yàn)诗赌。

項(xiàng)目中如果使用Druid


Maven依賴
       <druid.version>1.1.6</druid.version>
       <mysql-connector-java-version>5.1.44</mysql-connector-java-version>


        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-connector-java-version}</version>
        </dependency>
參數(shù)配置druid.properties
# 數(shù)據(jù)源類型
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 數(shù)據(jù)源驅(qū)動(dòng):MySql驅(qū)動(dòng)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 數(shù)據(jù)庫連接URL
spring.datasource.url=jdbc:mysql://localhost:3306/relaxheart?
# 編碼
useUnicode=true&characterEncoding=UTF-8
# 數(shù)據(jù)庫登錄名
datasource.username=root
# 數(shù)據(jù)庫登錄密碼
datasource.password=666666
# 初始化連接數(shù)量
spring.datasource.initialSize=1
# 最小空閑連接數(shù)
spring.datasource.minIdle=1
# 最大并發(fā)連接數(shù)
spring.datasource.maxActive=20
# 配置獲取連接等待超時(shí)的時(shí)間
spring.datasource.maxWait=60000
# 配置間隔多久才進(jìn)行一次檢測(cè)汗茄,檢測(cè)需要關(guān)閉的空閑連接,單位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 是否開啟PSCache铭若,如果用Oracle洪碳,則把poolPreparedStatements配置為true,mysql可以配置為false
spring.datasource.poolPreparedStatements=false
# 每個(gè)連接上PSCache的大小 
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 過濾器
spring.datasource.filters=stat,wall
# 是否打印執(zhí)行SQL
spring.jpa.show-sql=true
數(shù)據(jù)源XML配置
<!-- 數(shù)據(jù)源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <!-- 數(shù)據(jù)庫基本信息配置 -->
        <property name="url" value="${spring.datasource.url}" />
        <property name="username" value="${datasource.username}" />
        <property name="password" value="${datasource.password}" />
        <property name = "driverClassName" value = "${spring.datasource.driver-class-name}" />

        <!-- 初始化連接數(shù)量 -->
        <property name="initialSize" value="${spring.datasource.initialSize}" />
        <!-- 最小空閑連接數(shù) -->
        <property name="minIdle" value="${spring.datasource.minIdle}" />
        <!-- 最大并發(fā)連接數(shù) -->
        <property name="maxActive" value="${spring.datasource.maxActive}" />
        <!-- 配置獲取連接等待超時(shí)的時(shí)間 -->
        <property name="maxWait" value="${spring.datasource.maxWait}" />

        <!-- 配置間隔多久才進(jìn)行一次檢測(cè)叼屠,檢測(cè)需要關(guān)閉的空閑連接瞳腌,單位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="${spring.datasource.timeBetweenEvictionRunsMillis}" />

        <!-- 配置一個(gè)連接在池中最小生存的時(shí)間,單位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="${spring.datasource.minEvictableIdleTimeMillis}" />
        <property name="validationQuery" value="${spring.datasource.validationQuery}" />
        <property name="testWhileIdle" value="${spring.datasource.testWhileIdle}" />
        <property name="testOnBorrow" value="${spring.datasource.testOnBorrow}" />
        <property name="testOnReturn" value="${spring.datasource.testOnReturn}" />

        <!-- 打開PSCache镜雨,并且指定每個(gè)連接上PSCache的大小 如果用Oracle嫂侍,則把poolPreparedStatements配置為true,mysql可以配置為false荚坞。 -->
        <property name="poolPreparedStatements" value="${spring.datasource.poolPreparedStatements}" />
        <property name="maxPoolPreparedStatementPerConnectionSize"
                  value="${spring.datasource.maxPoolPreparedStatementPerConnectionSize}" />

        <!-- 配置監(jiān)控統(tǒng)計(jì)攔截的filters -->
        <property name="filters" value="${spring.datasource.filters}" />
    </bean>


<!-- 創(chuàng)建SqlSessionFactory,同時(shí)指定數(shù)據(jù)源 -->
    <!-- myBatis文件 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 配置數(shù)據(jù)庫表對(duì)應(yīng)的java實(shí)體類 -->
        <property name="typeAliasesPackage" value="cn.project.dal.object"></property>
        <!-- 自動(dòng)掃描entity目錄, 省掉Configuration.xml里的手工配置-->
        <property name="mapperLocations" value="classpath:config/mapping/*.xml" />
    </bean>

    <bean name="projectMapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.project.dal.inter"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>


<!-- ===================事務(wù)定義開始================= -->
    <!-- Ibatis事務(wù)管理器 -->

到這Druid數(shù)據(jù)源配置就完成了挑宠。接下來想要擴(kuò)展一點(diǎn)內(nèi)容,

擴(kuò)展點(diǎn)

怎么打開Druid的監(jiān)控統(tǒng)計(jì)功能

Druid的監(jiān)控統(tǒng)計(jì)功能是通過filter-chain擴(kuò)展實(shí)現(xiàn)西剥,如果你要打開監(jiān)控統(tǒng)計(jì)功能痹栖,配置StatFilter,具體看這里:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatFilter

內(nèi)置監(jiān)控中的Web和Spring關(guān)聯(lián)監(jiān)控怎么配置瞭空?
怎么配置防御SQL注入攻擊

Druid提供了WallFilter揪阿,它是基于SQL語義分析來實(shí)現(xiàn)防御SQL注入攻擊的。具體配置看這里:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE-wallfilter

Druid有沒有參考配置

不同的業(yè)務(wù)場(chǎng)景需求不同咆畏,你可以使用我們的參考配置南捂,但建議你仔細(xì)閱讀相關(guān)文檔,了解清楚之后做定制配置旧找。https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_DruidDataSource%E5%8F%82%E8%80%83%E9%85%8D%E7%BD%AE

我想日志記錄JDBC執(zhí)行的SQL溺健,如何配置

Druid提供了Log4jFilter、CommonsLogFilter和Slf4jFilter钮蛛,具體配置看這里https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_LogFilter

我的程序可能產(chǎn)生連接泄漏了鞭缭,有什么辦法剖膳?

Druid提供了多種監(jiān)測(cè)連接泄漏的手段,具體看這里:https://github.com/alibaba/druid/wiki/%E8%BF%9E%E6%8E%A5%E6%B3%84%E6%BC%8F%E7%9B%91%E6%B5%8B

在Druid中使用PSCache會(huì)有內(nèi)存占用過大問題么岭辣?

連接Oracle數(shù)據(jù)庫吱晒,打開PSCache,在其他的數(shù)據(jù)庫連接池都會(huì)存在內(nèi)存占用過多的問題沦童,Druid是唯一解決這個(gè)問題的連接池仑濒。具體看這里:https://github.com/alibaba/druid/wiki/Oracle%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%8BPreparedStatementCache%E5%86%85%E5%AD%98%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88

有沒有和其他數(shù)據(jù)庫連接池的對(duì)比?
從其他連接池遷移要注意什么偷遗?
Druid中有沒有類似Jboss DataSource中的ExceptionSorter

ExceptionSorter是JBoss DataSource中的優(yōu)秀特性墩瞳,Druid也有一樣功能的ExceptionSorter,但不用手動(dòng)配置氏豌,自動(dòng)識(shí)別生效的喉酌。具體看這里:https://github.com/alibaba/druid/wiki/ExceptionSorter_cn

Druid中的maxIdle為什么是沒用的?

maxIdle是Druid為了方便DBCP用戶遷移而增加的箩溃,maxIdle是一個(gè)混亂的概念瞭吃。連接池只應(yīng)該有maxPoolSize和minPoolSize,druid只保留了maxActive和minIdle涣旨,分別相當(dāng)于maxPoolSize和minPoolSize歪架。

我的應(yīng)用配置的是JNDI數(shù)據(jù)源,可以用DruidDataSource么霹陡?

DruidDataSource支持JNDI配置和蚪,具體看這里:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_JNDI_Tomcat
具體實(shí)現(xiàn)的類是這個(gè):com.alibaba.druid.pool.DruidDataSourceFactory,你可以閱讀代碼加深理解烹棉。

我的應(yīng)用已使用DBCP攒霹,是代碼中寫死的,怎樣更換為Druid浆洗?

可以的催束,Druid提供了一個(gè)中完全平滑遷移DBCP的辦法。

這種用法,使得可以在一些非自己開發(fā)的應(yīng)用中使用Druid摘昌,例如在sonar中部署druid速妖,sonar是一個(gè)使用jruby開發(fā)的web應(yīng)用,寫死了DBCP聪黎,只能夠通過這種方法來更換罕容。

我想試用快照版本,怎么獲取锦秒?

直接獲取快照版本的地址是:http://code.alibabatech.com/mvn/snapshots/com/alibaba/druid/

注意:快照版本慎用露泊,可能會(huì)有不可預(yù)知的問題

有一些SQL執(zhí)行很慢,我希望日志記錄下來脂崔,怎么設(shè)置滤淳?

運(yùn)維和DBA都不希望把密碼明文直接寫在配置文件中梧喷,Druid提供了數(shù)據(jù)庫秘密加密的功能砌左。具體看這里:https://github.com/alibaba/druid/wiki/%E4%BD%BF%E7%94%A8ConfigFilter

如何參與Druid的開發(fā)

Druid是一個(gè)通過github開源的項(xiàng)目,github的特性铺敌,使得你很容易參與其中汇歹。這里有詳細(xì)說明https://github.com/alibaba/druid/wiki/%E5%A6%82%E4%BD%95%E5%8F%82%E4%B8%8E

Druid的發(fā)布周期是怎樣?

Druid是一個(gè)活躍的項(xiàng)目偿凭,長(zhǎng)期維護(hù)产弹。每個(gè)月有一個(gè)發(fā)布窗口,除非遇到重大bug和非常緊急的需求弯囊,否則都是每個(gè)月最多發(fā)布一次痰哨。如果沒有足夠多的需求,發(fā)布窗口就不會(huì)被使用匾嘱。

如果DruidDataSource在init的時(shí)候失敗了斤斧,不再使用,是否需要close

是的霎烙,如果DruidDataSource不再使用撬讽,必須調(diào)用close來釋放資源,釋放的資源包括關(guān)閉Create和Destory線程悬垃。

DruidDataSource支持哪些數(shù)據(jù)庫游昼?
mysql   支持,大規(guī)模使用
oracle  支持尝蠕,大規(guī)模使用
sqlserver   支持
postgres    支持
db2 支持
h2  支持
derby   支持
sqlite  支持
sybase  支持
Oracle下jdbc executeBatch時(shí)烘豌,更新行數(shù)計(jì)算不正確

使用jdbc的executeBatch 方法,如果數(shù)據(jù)庫為oracle看彼,則無論是否成功更新到數(shù)據(jù)廊佩,返回值都是-2,而不是真正被sql更新到的記錄數(shù)闲昭,這是Oracle JDBC Driver的問題罐寨,Druid不作特殊處理。

如何保存監(jiān)控記錄

https://github.com/alibaba/druid/wiki/%E6%80%8E%E4%B9%88%E4%BF%9D%E5%AD%98Druid%E7%9A%84%E7%9B%91%E6%8E%A7%E8%AE%B0%E5%BD%95

我想Log輸出SQL執(zhí)行的信息怎么辦序矩?

https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_LogFilter

如何配置Druid內(nèi)置的log實(shí)現(xiàn)

https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AEdruid%E5%86%85%E7%BD%AE%E7%9A%84log%E5%AE%9E%E7%8E%B0

文章來源:https://www.relaxheart.cn/to/master/blog?uuid=76

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鸯绿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓶蝴,老刑警劉巖毒返,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異舷手,居然都是意外死亡拧簸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門男窟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盆赤,“玉大人,你說我怎么就攤上這事歉眷∥” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵汗捡,是天一觀的道長(zhǎng)淑际。 經(jīng)常有香客問我,道長(zhǎng)扇住,這世上最難降的妖魔是什么春缕? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮艘蹋,結(jié)果婚禮上锄贼,老公的妹妹穿的比我還像新娘。我一直安慰自己簿训,他們只是感情好咱娶,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著强品,像睡著了一般膘侮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上的榛,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天琼了,我揣著相機(jī)與錄音,去河邊找鬼夫晌。 笑死雕薪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晓淀。 我是一名探鬼主播所袁,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼凶掰!你這毒婦竟也來了燥爷?” 一聲冷哼從身側(cè)響起蜈亩,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎前翎,沒想到半個(gè)月后稚配,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡港华,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年道川,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片立宜。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡冒萄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赘理,到底是詐尸還是另有隱情宦言,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布商模,位于F島的核電站,受9級(jí)特大地震影響蜘澜,放射性物質(zhì)發(fā)生泄漏施流。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一鄙信、第九天 我趴在偏房一處隱蔽的房頂上張望瞪醋。 院中可真熱鬧,春花似錦装诡、人聲如沸银受。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宾巍。三九已至,卻和暖如春渔伯,著一層夾襖步出監(jiān)牢的瞬間顶霞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工锣吼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留选浑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓玄叠,卻偏偏與公主長(zhǎng)得像古徒,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子读恃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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