SpringBoot之集成Druid數(shù)據(jù)庫連接池方式
前言
在軟件系統(tǒng)中都會(huì)使用到數(shù)據(jù)庫,是開發(fā)中大型系統(tǒng)不可缺少的。但如果對(duì)數(shù)據(jù)庫資源沒有很好地管理,往往會(huì)直接導(dǎo)致系統(tǒng)的穩(wěn)定。隨著系統(tǒng)流量、用戶的增加,會(huì)逐步顯露。
使用數(shù)據(jù)庫連接池可以更好、更高效的管理數(shù)據(jù)庫連接資源,我們可以直接使用第三方服務(wù),不必自己思索數(shù)據(jù)庫連接的管理。
數(shù)據(jù)庫連接池技術(shù)有:DBCP 、tomcat-jdbc、C3P0、HikariCP、Druid 等。
優(yōu)先推薦 Druid。它作為國(guó)貨,更加符合國(guó)人的思維,功能豐富,還經(jīng)歷了千錘百煉。
一、數(shù)據(jù)庫連接池
數(shù)據(jù)庫連接是一種關(guān)鍵的有限的昂貴的資源,這一點(diǎn)在多用戶的網(wǎng)頁應(yīng)用程序中體現(xiàn)得尤為突出。對(duì)數(shù)據(jù)庫連接的管理能顯著影響到整個(gè)應(yīng)用程序的伸縮性和健壯性,影響到程序的性能指標(biāo)。數(shù)據(jù)庫連接池正是針對(duì)這個(gè)問題提出來的。
數(shù)據(jù)庫連接池負(fù)責(zé)分配、管理和釋放數(shù)據(jù)庫連接,它允許應(yīng)用程序重復(fù)使用一個(gè)現(xiàn)有的數(shù)據(jù)庫連接,而不是再重新建立一個(gè);釋放空閑時(shí)間超過最大空閑時(shí)間的數(shù)據(jù)庫連接來避免因?yàn)闆]有釋放數(shù)據(jù)庫連接而引起的數(shù)據(jù)庫連接遺漏。這項(xiàng)技術(shù)能明顯提高對(duì)數(shù)據(jù)庫操作的性能。
數(shù)據(jù)庫連接池優(yōu)點(diǎn):
- 資源重用
- 更快的系統(tǒng)響應(yīng)速度
- 高效資源分配手段
- 統(tǒng)一的連接管理,避免數(shù)據(jù)庫連接泄漏
二、SpringBoot數(shù)據(jù)庫連接池
SpringBoot 2.2.6 文檔說明:

- 由于
HikariCP的性能和并發(fā)性。如果有HikariCP,SpringBoot 會(huì)選擇它。 - 否則,如果
Tomcat數(shù)據(jù)源連接池可用,也可以使用它。 - 如果
HikariCP和Tomcat數(shù)據(jù)源連接池都不可用,并且如果Commons DBCP2可用,就使用它。
可以使用 spring.datasource.type 屬性來指定要使用的連接池。
如果使用 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa,將自動(dòng)獲得對(duì) HikariCP 的依賴。
三、Druid數(shù)據(jù)庫連接池
Druid 連接池是阿里巴巴開源的數(shù)據(jù)庫連接池項(xiàng)目(阿里巴巴數(shù)據(jù)庫事業(yè)部出品)。Druid 連接池為監(jiān)控而生,內(nèi)置強(qiáng)大的監(jiān)控功能,監(jiān)控特性不影響性能。功能強(qiáng)大,能防 SQL注入,內(nèi)置 Loging 能診斷 Hack 應(yīng)用行為。
Druid 是一個(gè) JDBC 組件庫,包含數(shù)據(jù)庫連接池、SQL Parser 等組件, 被大量業(yè)務(wù)和技術(shù)產(chǎn)品使用或集成,經(jīng)歷過最嚴(yán)苛線上業(yè)務(wù)場(chǎng)景考驗(yàn)。是 Java 語言中最好的數(shù)據(jù)庫連接池。
官方提供對(duì)比:Druid 連接池在性能、監(jiān)控、診斷、安全、擴(kuò)展性這些方面遠(yuǎn)遠(yuǎn)超出競(jìng)品。
| 功能類別 | 功能 | Druid | HikariCP | DBCP | Tomcat-jdbc | C3P0 |
|---|---|---|---|---|---|---|
| 性能 | PSCache | 是 | 否 | 是 | 是 | 是 |
| LRU | 是 | 否 | 是 | 是 | 是 | |
| SLB負(fù)載均衡支持 | 是 | 否 | 否 | 否 | 否 | |
| 穩(wěn)定性 | ExceptionSorter | 是 | 否 | 否 | 否 | 否 |
| 擴(kuò)展 | 擴(kuò)展 | Filter | JdbcIntercepter | |||
| 監(jiān)控 | 監(jiān)控方式 | jmx/log/http | jmx/metrics | jmx | jmx | jmx |
| 支持SQL級(jí)監(jiān)控 | 是 | 否 | 否 | 否 | 否 | |
| Spring/Web關(guān)聯(lián)監(jiān)控 | 是 | 否 | 否 | 否 | 否 | |
| 診斷支持 | LogFilter | 否 | 否 | 否 | 否 | |
| 連接泄露診斷 | logAbandoned | 否 | 否 | 否 | 否 | |
| 安全 | SQL防注入 | 是 | 無 | 無 | 無 | 無 |
| 支持配置加密 | 是 | 否 | 否 | 否 | 否 |
四、SpringBoot集成Druid
1.環(huán)境說明
- 開發(fā)工具:IDEA 2019.3.1
- 框架版本:SpringBoot 2.2.6
- 數(shù)據(jù)庫:MySql 8.0.19
- 數(shù)據(jù)庫連接池:Druid 1.1.9
2.集成步驟
(1)添加maven依賴
<!-- Druid 數(shù)據(jù)庫連接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.9</version> </dependency>
(2)Druid配置
application.properties文件
# ======================================== Druid 配置 ========================================= # # 要使用的連接池實(shí)現(xiàn)的全限定名。默認(rèn)情況下,它是從類路徑自動(dòng)檢測(cè)到的。 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource # JDBC配置: # JDBC驅(qū)動(dòng)程序的完全限定名。默認(rèn)情況下基于URL自動(dòng)檢測(cè) spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver # 數(shù)據(jù)庫的JDBC URL spring.datasource.druid.url=jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8 # 數(shù)據(jù)庫登錄用戶名 spring.datasource.druid.username=root # 數(shù)據(jù)庫登錄密碼 spring.datasource.druid.password=root # 連接池配置: # 初始化時(shí)建立物理連接的個(gè)數(shù) spring.datasource.druid.initial-size=2 # 最大連接池?cái)?shù)量 spring.datasource.druid.max-active=10 # 最小連接池?cái)?shù)量 spring.datasource.druid.min-idle=2 # 屬性類型是字符串,通過別名的方式配置擴(kuò)展插件,配置多個(gè)英文逗號(hào)分隔。 # 常用的插件有:監(jiān)控統(tǒng)計(jì)用的filter:stat,日志用的filter:log4j,防御sql注入的filter:wall spring.datasource.druid.filters=stat,wall # 監(jiān)控配置: # WebStatFilter配置 # 是否啟用StatFilter默認(rèn)值false spring.datasource.druid.web-stat-filter.enabled=true spring.datasource.druid.web-stat-filter.url-pattern=/* # 排除不必要的url spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.jpg,*.css,*.ico,/druid/* # 是否開啟session統(tǒng)計(jì)功能 spring.datasource.druid.web-stat-filter.session-stat-enable=true # session最大數(shù),缺省sessionStatMaxCount是1000個(gè) spring.datasource.druid.web-stat-filter.session-stat-max-count=500 # 用戶user信息保存在session中的sessionName,druid能夠知道當(dāng)前的session用戶 spring.datasource.druid.web-stat-filter.principal-session-name=web_user # 用戶user信息保存在cookie 中的cookieName,druid能夠知道當(dāng)前的用戶 #spring.datasource.druid.web-stat-filter.principal-cookie-name= # 監(jiān)控單個(gè)url調(diào)用的sql列表 spring.datasource.druid.web-stat-filter.profile-enable=true # StatViewServlet配置 # 是否啟用StatViewServlet(監(jiān)控頁面)默認(rèn)值為false(考慮到安全問題默認(rèn)并未啟動(dòng),如需啟用建議設(shè)置密碼或白名單以保障安全) spring.datasource.druid.stat-view-servlet.enabled=true # 訪問url模式 spring.datasource.druid.stat-view-servlet.url-pattern=/druid/* # 是否允許清空統(tǒng)計(jì)數(shù)據(jù) spring.datasource.druid.stat-view-servlet.reset-enable=true # 監(jiān)控頁面訪問用戶名 spring.datasource.druid.stat-view-servlet.login-username=admin # 監(jiān)控頁面訪問密碼 spring.datasource.druid.stat-view-servlet.login-password=admin # -訪問控制: # -deny優(yōu)先于allow,如果在deny列表中,就算在allow列表中,也會(huì)被拒絕。 # -如果allow沒有配置或者為空,則允許所有訪問) # -由于匹配規(guī)則不支持IPV6,配置了allow或者deny之后,會(huì)導(dǎo)致IPV6無法訪問 # 訪問控制,白名單IP #spring.datasource.druid.stat-view-servlet.allow= # 訪問控制,黑名單IP #spring.datasource.druid.stat-view-servlet.deny= # Spring監(jiān)控配置 # Spring監(jiān)控AOP切入點(diǎn),如x.y.z.service.*,配置多個(gè)英文逗號(hào)分隔 #spring.datasource.druid.aop-patterns= # ======================================== Druid 配置 結(jié)束 ========================================= #
DruidDataSource 配置屬性列表
DruidDataSource 配置兼容 DBCP,但個(gè)別配置的語意有所區(qū)別。
| 配置 | 缺省值 | 說明 |
|---|---|---|
| name | 配置這個(gè)屬性的意義在于,如果存在多個(gè)數(shù)據(jù)源,監(jiān)控的時(shí)候可以通過名字來區(qū)分開來。如果沒有配置,將會(huì)生成一個(gè)名字,格式是:"DataSource-" + System.identityHashCode(this). 另外配置此屬性至少在1.0.5版本中是不起作用的,強(qiáng)行設(shè)置name會(huì)出錯(cuò)。 | |
| url | 連接數(shù)據(jù)庫的url,不同數(shù)據(jù)庫不一樣。例如: mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto | |
| username | 連接數(shù)據(jù)庫的用戶名 | |
| password | 連接數(shù)據(jù)庫的密碼。如果你不希望密碼直接寫在配置文件中,可以使用ConfigFilter。 | |
| driverClassName | 根據(jù)url自動(dòng)識(shí)別 | 這一項(xiàng)可配可不配,如果不配置druid會(huì)根據(jù)url自動(dòng)識(shí)別dbType,然后選擇相應(yīng)的driverClassName |
| initialSize | 0 | 初始化時(shí)建立物理連接的個(gè)數(shù)。初始化發(fā)生在顯示調(diào)用init方法,或者第一次getConnection時(shí) |
| maxActive | 8 | 最大連接池?cái)?shù)量 |
| minIdle | 最小連接池?cái)?shù)量 | |
| maxWait | 獲取連接時(shí)最大等待時(shí)間,單位毫秒。配置了maxWait之后,缺省啟用公平鎖,并發(fā)效率會(huì)有所下降,如果需要可以通過配置useUnfairLock屬性為true使用非公平鎖。 | |
| poolPreparedStatements | false | 是否緩存preparedStatement,也就是PSCache。PSCache對(duì)支持游標(biāo)的數(shù)據(jù)庫性能提升巨大,比如說oracle。在mysql下建議關(guān)閉。 |
| maxPoolPreparedStatementPerConnectionSize | -1 | 要啟用PSCache,必須配置大于0,當(dāng)大于0時(shí),poolPreparedStatements自動(dòng)觸發(fā)修改為true。在Druid中,不會(huì)存在Oracle下PSCache占用內(nèi)存過多的問題,可以把這個(gè)數(shù)值配置大一些,比如說100 |
| validationQuery | 用來檢測(cè)連接是否有效的sql,要求是一個(gè)查詢語句,常用select 'x'。如果validationQuery為null,testOnBorrow、testOnReturn、testWhileIdle都不會(huì)起作用。 | |
| validationQueryTimeout | 單位:秒,檢測(cè)連接是否有效的超時(shí)時(shí)間。底層調(diào)用jdbc Statement對(duì)象的void setQueryTimeout(int seconds)方法 | |
| testOnBorrow | true | 申請(qǐng)連接時(shí)執(zhí)行validationQuery檢測(cè)連接是否有效,做了這個(gè)配置會(huì)降低性能。 |
| testOnReturn | false | 歸還連接時(shí)執(zhí)行validationQuery檢測(cè)連接是否有效,做了這個(gè)配置會(huì)降低性能。 |
| testWhileIdle | false | 建議配置為true,不影響性能,并且保證安全性。申請(qǐng)連接的時(shí)候檢測(cè),如果空閑時(shí)間大于timeBetweenEvictionRunsMillis,執(zhí)行validationQuery檢測(cè)連接是否有效。 |
| keepAlive | false(1.0.28) | 連接池中的minIdle數(shù)量以內(nèi)的連接,空閑時(shí)間超過minEvictableIdleTimeMillis,則會(huì)執(zhí)行keepAlive操作。 |
| timeBetweenEvictionRunsMillis | 1分鐘(1.0.14) | 有兩個(gè)含義:1) Destroy線程會(huì)檢測(cè)連接的間隔時(shí)間,如果連接空閑時(shí)間大于等于minEvictableIdleTimeMillis則關(guān)閉物理連接。2) testWhileIdle的判斷依據(jù),詳細(xì)看testWhileIdle屬性的說明 |
| minEvictableIdleTimeMillis | 連接保持空閑而不被驅(qū)逐的最小時(shí)間 | |
| connectionInitSqls | 物理連接初始化的時(shí)候執(zhí)行的sql | |
| exceptionSorter | 根據(jù)dbType自動(dòng)識(shí)別 | 當(dāng)數(shù)據(jù)庫拋出一些不可恢復(fù)的異常時(shí),拋棄連接 |
| filters | 屬性類型是字符串,通過別名的方式配置擴(kuò)展插件,常用的插件有:監(jiān)控統(tǒng)計(jì)用的filter:stat日志用的filter:log4j防御sql注入的filter:wall | |
| proxyFilters | 類型是List<com.alibaba.druid.filter.Filter>,如果同時(shí)配置了filters和proxyFilters,是組合關(guān)系,并非替換關(guān)系 |
(3)監(jiān)控頁面
Druid 內(nèi)置提供了一個(gè) StatViewServlet 用于展示 Druid 的統(tǒng)計(jì)信息。
這個(gè) StatViewServlet 的用途包括:
- 提供監(jiān)控信息展示的 html 頁面
- 提供監(jiān)控信息的 JSON API
輸入 http://127.0.0.1:8080/demo/druid 進(jìn)入 Druid 監(jiān)控登錄頁面,輸入配置中的用戶名和密碼。

進(jìn)入到 Druid 監(jiān)控頁面,可以看到非常全面的系統(tǒng)監(jiān)控?cái)?shù)據(jù)。

總結(jié)
目前只是 SpringBoot 集成了 Druid 連接池,并可以進(jìn)入監(jiān)控頁面進(jìn)行查看相關(guān)監(jiān)控?cái)?shù)據(jù)。后期可以將監(jiān)控頁面嵌入到系統(tǒng)中,或是直接獲取監(jiān)控?cái)?shù)據(jù)自行展示。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java無界阻塞隊(duì)列DelayQueue詳細(xì)解析
這篇文章主要介紹了Java無界阻塞隊(duì)列DelayQueue詳細(xì)解析,DelayQueue是一個(gè)支持時(shí)延獲取元素的無界阻塞隊(duì)列,隊(duì)列使用PriorityQueue來實(shí)現(xiàn),隊(duì)列中的元素必須實(shí)現(xiàn)Delayed接口,在創(chuàng)建元素時(shí)可以指定多久才能從隊(duì)列中獲取當(dāng)前元素,需要的朋友可以參考下2023-12-12
Spring?Security權(quán)限控制的實(shí)現(xiàn)接口
這篇文章主要介紹了Spring?Security的很多功能,在這些眾多功能中,我們知道其核心功能其實(shí)就是認(rèn)證+授權(quán)。Spring教程之Spring?Security的四種權(quán)限控制方式2023-03-03
玩轉(zhuǎn)spring boot MVC應(yīng)用(2)
玩轉(zhuǎn)spring boot,如何快速搭建一個(gè)MCV程序?這篇文章為大家詳細(xì)主要介紹了一個(gè)MCV程序的快速搭建過程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
在Struts2中如何將父類屬性序列化為JSON格式的解決方法
本篇文章,小編將為大家介紹關(guān)于在Struts2中如何將父類屬性序列化為JSON格式的解決方法,有需要的朋友可以參考一下2013-04-04
淺談使用Java Web獲取客戶端真實(shí)IP的方法示例詳解
這篇文章主要介紹了使用Java-Web獲取客戶端真實(shí)IP的方法示例詳解。一般我們無法獲取客戶端真實(shí)IP,原因是:當(dāng)我們通過request獲取客戶端IP時(shí),自身服務(wù)器通常會(huì)為了保護(hù)信息或者負(fù)載均衡的目的,對(duì)自身服務(wù)器做反向代理。對(duì)此感興趣可以了解一下2020-07-07

