Druid簡介(Spring Boot + Mybatis + Druid數(shù)據源【官方start】)

Druid的簡介

Druid是一個非常優(yōu)秀的數(shù)據庫連接池。在功能、性能、擴展性方面,都超過其他數(shù)據庫連接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。

Druid已經在阿里巴巴部署了超過600個應用,經過一年多生產環(huán)境大規(guī)模部署的嚴苛考驗。

Druid是一個JDBC組件,它包括三個部分:

  • 基于Filter-Chain模式的插件體系。

  • DruidDataSource 高效可管理的數(shù)據庫連接池。

  • SQLParser

Druid的功能

兼容DBCP

Druid提供了一個高效、功能強大、可擴展性好的數(shù)據庫連接池。從DBCP遷移到Druid,只需要修改數(shù)據源的實現(xiàn)類就可以了。

強大的監(jiān)控特性

Druid內置了一個功能強大的StatFilter插件可以監(jiān)控數(shù)據庫訪問性能,可以清楚知道連接池和SQL的工作情況。

  • 監(jiān)控SQL的執(zhí)行時間、ResultSet持有時間、返回行數(shù)、更新行數(shù)、錯誤次數(shù)、錯誤堆棧信息。

  • SQL執(zhí)行的耗時區(qū)間分布。什么是耗時區(qū)間分布呢?比如說,某個SQL執(zhí)行了1000次,其中0-1毫秒區(qū)間50次,1-10毫秒800次,10-100毫秒100次,100-1000毫秒30次,1-10秒15次,10秒以上5次。通過耗時區(qū)間分布,能夠非常清楚知道SQL的執(zhí)行耗時情況。

  • 監(jiān)控連接池的物理連接創(chuàng)建和銷毀次數(shù)、邏輯連接的申請和關閉次數(shù)、非空等待次數(shù)、PSCache命中率等。

數(shù)據庫密碼加密

直接把數(shù)據庫密碼寫在配置文件中,這是不好的行為,容易導致安全問題。DruidDruiver和DruidDataSource都支持PasswordCallback。

SQL執(zhí)行日志

Druid提供了不同的LogFilter,能夠支持Common-Logging、Log4j和JdkLog,你可以按需要選擇相應的LogFilter,監(jiān)控你應用的數(shù)據庫訪問情況。

擴展JDBC

如果你要對JDBC層有編程的需求,可以通過Druid提供的Filter機制,很方便編寫JDBC層的擴展插件。

Druid在DruidDataSourc和ProxyDriver上提供了Filter-Chain模式的擴展API,類似Serlvet的Filter,配置Filter攔截JDBC的方法調用。

SQLParser

SQL Parser是Druid的一個重要組成部分,它提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,這是一個手寫的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象語法樹很方便。

簡單SQL語句用時10微秒以內,復雜SQL用時30微秒。

通過Druid提供的SQL Parser可以在JDBC層攔截SQL做相應處理,比如防御SQL注入(WallFilter)、合并統(tǒng)計沒有參數(shù)化的SQL(StatFilter的mergeSql)、SQL格式化、分庫分表。

http://blog.csdn.net/qq_30444003/article/details/50795116

<style>table th:first-of-type { width: 100px;}</style>

Druid的配置詳解

配置 缺省值 說明
name 配置這個屬性的意義在于,如果存在多個數(shù)據源,監(jiān)控的時候可以通過名字來區(qū)分開來。如果沒有配置,將會生成一個名字,格式是:"DataSource-" + System.identityHashCode(this). 另外配置此屬性至少在1.0.5版本中是不起作用的,強行設置name會出錯。詳情-點此處
url 連接數(shù)據庫的url,不同數(shù)據庫不一樣。例如:<br />mysql : jdbc:mysql://10.20.153.104:3306/druid2<br /> oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto
username 連接數(shù)據庫的用戶名
password 連接數(shù)據庫的密碼。如果你不希望密碼直接寫在配置文件中,可以使用ConfigFilter。詳細看這里
driverClassName 根據url自動識別 這一項可配可不配,如果不配置druid會根據url自動識別dbType,然后選擇相應的driverClassName
initialSize 0 初始化時建立物理連接的個數(shù)。初始化發(fā)生在顯示調用init方法,或者第一次getConnection時
maxActive 8 最大連接池數(shù)量
maxIdle 8 已經不再使用,配置了也沒效果
minIdle 最小連接池數(shù)量
maxWait 獲取連接時最大等待時間,單位毫秒。配置了maxWait之后,缺省啟用公平鎖,并發(fā)效率會有所下降,如果需要可以通過配置useUnfairLock屬性為true使用非公平鎖。
poolPreparedStatements false 是否緩存preparedStatement,也就是PSCache。PSCache對支持游標的數(shù)據庫性能提升巨大,比如說oracle。在mysql下建議關閉。
maxPoolPreparedStatementPerConnectionSize -1 要啟用PSCache,必須配置大于0,當大于0時,poolPreparedStatements自動觸發(fā)修改為true。在Druid中,不會存在Oracle下PSCache占用內存過多的問題,可以把這個數(shù)值配置大一些,比如說100
validationQuery 用來檢測連接是否有效的sql,要求是一個查詢語句,常用select 'x'。如果validationQuery為null,testOnBorrow、testOnReturn、testWhileIdle都不會起作用。
validationQueryTimeout 單位:秒,檢測連接是否有效的超時時間。底層調用jdbc Statement對象的void setQueryTimeout(int seconds)方法
testOnBorrow true 申請連接時執(zhí)行validationQuery檢測連接是否有效,做了這個配置會降低性能。
testOnReturn false 歸還連接時執(zhí)行validationQuery檢測連接是否有效,做了這個配置會降低性能。
testWhileIdle false 建議配置為true,不影響性能,并且保證安全性。申請連接的時候檢測,如果空閑時間大于timeBetweenEvictionRunsMillis,執(zhí)行validationQuery檢測連接是否有效。
timeBetweenEvictionRunsMillis 1分鐘(1.0.14) 有兩個含義:<br />1) Destroy線程會檢測連接的間隔時間,如果連接空閑時間大于等于minEvictableIdleTimeMillis則關閉物理連接。<br />2) testWhileIdle的判斷依據,詳細看testWhileIdle屬性的說明
numTestsPerEvictionRun 30分鐘(1.0.14) 不再使用,一個DruidDataSource只支持一個EvictionRun
minEvictableIdleTimeMillis 連接保持空閑而不被驅逐的最長時間
connectionInitSqls 物理連接初始化的時候執(zhí)行的sql
exceptionSorter 根據dbType自動識別 當數(shù)據庫拋出一些不可恢復的異常時,拋棄連接
filters 屬性類型是字符串,通過別名的方式配置擴展插件,常用的插件有:<br />監(jiān)控統(tǒng)計用的filter:stat<br />日志用的filter:log4j<br />防御sql注入的filter:wall
proxyFilters 類型是List<com.alibaba.druid.filter.Filter>,如果同時配置了filters和proxyFilters,是組合關系,并非替換關系

Druid源碼

https://github.com/alibaba/druid/wiki

Druid常見問題

https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

項目實踐

我們使用的是Spring boot + mybatis + Druid(官方start)的架構

目前Spring Boot中默認支持的連接池有dbcp,dbcp2, tomcat, hikari四種連接池。

由于Druid暫時不在Spring Bootz中的直接支持。現(xiàn)在阿里官方對Spring Boot做了優(yōu)化,寫了一個start,我們在Spring Boot項目中直接依賴即可。

導入依賴包

<!-- 數(shù)據庫驅動 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Mybatis -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.0</version>
</dependency>
<!--Mybatis 分頁插件 pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.1.1</version>
</dependency>
<!-- Druid連接池包 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.1</version>
</dependency>

配置數(shù)據源

Druid Start Github地址

application.properties配置信息:

#https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
spring.datasource.druid.url=jdbc:mysql://localhost:3306/ssb_test
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.username=root
spring.datasource.druid.password=root
# 初始化大小,最小,最大
spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.max-active=20
# 配置獲取連接等待超時的時間
spring.datasource.druid.max-wait=60000
# 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒
spring.datasource.druid.time-between-eviction-runs-millis=60000
# 配置一個連接在池中最小生存的時間,單位是毫秒
spring.datasource.druid.min-evictable-idle-time-millis=300000
#檢測連接是否有效的sql
spring.datasource.druid.validation-query=SELECT 'x'
spring.datasource.druid.validation-query-timeout=60000
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false
# PSCache Mysql下建議關閉
spring.datasource.druid.pool-prepared-statements=false
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=-1
#spring.datasource.druid.max-open-prepared-statements= #等價于上面的max-pool-prepared-statement-per-connection-size

#mybatis
#entity掃描的包名
mybatis.type-aliases-package=com.xiaolyuh.domain.model
#Mapper.xml所在的位置
mybatis.mapper-locations=classpath*:/mybaits/*Mapper.xml
#開啟MyBatis的二級緩存
mybatis.configuration.cache-enabled=true

#pagehelper
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql

到這里我們數(shù)據源就配置好了,寫一個測試類我們可以查看數(shù)據源是否生效。

測試類

package com.xiaolyuh;

import com.alibaba.fastjson.JSON;
import com.xiaolyuh.config.DruidDataSourceProperty;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;

import javax.sql.DataSource;

@RunWith(SpringRunner.class)
@SpringBootTest
public class DataSourceTests {

    @Autowired
    ApplicationContext applicationContext;

    @Test
    public void testDataSource() throws Exception {
        // 獲取配置的數(shù)據源
        DataSource dataSource = applicationContext.getBean(DataSource.class);
        // 查看配置數(shù)據源信息
        System.out.println(dataSource.getClass().getName());
    }

}

打印日志:

com.alibaba.druid.pool.DruidDataSource
{"connectionProperties":"druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000","driverClassName":"com.mysql.jdbc.Driver","filters":"stat,wall,log4j","initialSize":5,"maxActive":20,"maxPoolPreparedStatementPerConnectionSize":-1,"maxWait":60000,"minEvictableIdleTimeMillis":300000,"minIdle":5,"password":"root","poolPreparedStatements":false,"testOnBorrow":false,"testOnReturn":false,"testWhileIdle":true,"timeBetweenEvictionRunsMillis":60000,"url":"jdbc:mysql://localhost:3306/ssb_test","useGlobalDataSourceStat":true,"username":"root","validationQuery":"SELECT 'x'"}
2017-07-02 11:29:04.183  INFO 340 --- [       Thread-2] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@11fc564b: startup date [Sun Jul 02 11:28:58 CST 2017]; root of context hierarchy

Druid監(jiān)控的配置

下面我們來說一下Druid監(jiān)控的配置:

application.properties配置:

# 配置監(jiān)控統(tǒng)計攔截的filters,去掉后監(jiān)控界面sql無法統(tǒng)計,'wall'用于防火墻
spring.datasource.druid.filters=stat,wall,log4j

使用這個filter的配置,開啟對監(jiān)控的支持。屬性類型是字符串,通過別名的方式配置擴展插件,常用的插件有:

  • 監(jiān)控統(tǒng)計用的filter:stat
  • 日志用的filter:log4j
  • 防御sql注入的filter:wall

WebStatFilter配置

在application.properties文件中加入如下配置:

# WebStatFilter配置,說明請參考Druid Wiki,配置_配置WebStatFilter
#啟動項目后訪問 http://127.0.0.1:8080/druid
#是否啟用StatFilter默認值true
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
#缺省sessionStatMaxCount是1000個
spring.datasource.druid.web-stat-filter.session-stat-max-count=1000
#關閉session統(tǒng)計功能
spring.datasource.druid.web-stat-filter.session-stat-enable=false
#配置principalSessionName,使得druid能夠知道當前的session的用戶是誰
#如果你session中保存的是非string類型的對象,需要重載toString方法
spring.datasource.druid.web-stat-filter.principalSessionName=xxx.user
#如果user信息保存在cookie中,你可以配置principalCookieName,使得druid知道當前的user是誰
spring.datasource.druid.web-stat-filter.principalCookieName=xxx.user
#druid 0.2.7版本開始支持profile,配置profileEnable能夠監(jiān)控單個url調用的sql列表。
spring.datasource.druid.web-stat-filter.profile-enable=false

StatViewServlet配置

在application.properties文件中加入如下配置:

# StatViewServlet配置,說明請參考Druid Wiki,配置_StatViewServlet配置
#啟動項目后訪問 http://127.0.0.1:8080/druid
#是否啟用StatViewServlet默認值true
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.urlPattern=/druid/*
#禁用HTML頁面上的“Reset All”功能
spring.datasource.druid.stat-view-servlet.resetEnable=false
#用戶名
spring.datasource.druid.stat-view-servlet.loginUsername=admin
#密碼
spring.datasource.druid.stat-view-servlet.loginPassword=admin
#IP白名單(沒有配置或者為空,則允許所有訪問)
spring.datasource.druid.stat-view-servlet.allow=127.0.0.1,192.168.163.1
#IP黑名單 (存在共同時,deny優(yōu)先于allow)
spring.datasource.druid.stat-view-servlet.deny=192.168.1.73

打開監(jiān)控界面

瀏覽器中輸入:http://localhost/druid

輸入用戶名和密碼,上面配置的。

image

源碼

https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases

spring-boot-student-mybatis-druid-2 工程

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

推薦閱讀更多精彩內容