配置信息
maven 引入
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${alibaba-druid.version}</version>
</dependency>
配置属性
推荐配置
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc_url}" />
<property name="username" value="${jdbc_user}" />
<property name="password" value="${jdbc_password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="5" />
<property name="minIdle" value="5" />
<property name="maxActive" value="10" />
<!-- 配置从连接池获取连接等待超时的时间 -->
<property name="maxWait" value="10000" />
<!-- 配置间隔多久启动一次DestroyThread,对连接池内的连接才进行一次检测,单位是毫秒。
检测时:1.如果连接空闲并且超过minIdle以外的连接,如果空闲时间超过minEvictableIdleTimeMillis设置的值则直接物理关闭。2.在minIdle以内的不处理。
-->
<property name="timeBetweenEvictionRunsMillis" value="600000" />
<!-- 配置一个连接在池中最大空闲时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<!-- 设置从连接池获取连接时是否检查连接有效性,true时,每次都检查;false时,不检查 -->
<property name="testOnBorrow" value="false" />
<!-- 设置往连接池归还连接时是否检查连接有效性,true时,每次都检查;false时,不检查 -->
<property name="testOnReturn" value="false" />
<!-- 设置从连接池获取连接时是否检查连接有效性,true时,如果连接空闲时间超过minEvictableIdleTimeMillis进行检查,否则不检查;false时,不检查 -->
<property name="testWhileIdle" value="true" />
<!-- 检验连接是否有效的查询语句。如果数据库Driver支持ping()方法,则优先使用ping()方法进行检查,否则使用validationQuery查询进行检查。(Oracle jdbc Driver目前不支持ping方法) -->
<property name="validationQuery" value="select 1 from dual" />
<!-- 单位:秒,检测连接是否有效的超时时间。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法 -->
<!-- <property name="validationQueryTimeout" value="1" /> -->
<!-- 打开后,增强timeBetweenEvictionRunsMillis的周期性连接检查,minIdle内的空闲连接,每次检查强制验证连接有效性. 参考:https://github.com/alibaba/druid/wiki/KeepAlive_cn -->
<property name="keepAlive" value="true" />
<!-- 连接泄露检查,打开removeAbandoned功能 , 连接从连接池借出后,长时间不归还,将触发强制回连接。回收周期随timeBetweenEvictionRunsMillis进行,如果连接为从连接池借出状态,并且未执行任何sql,并且从借出时间起已超过removeAbandonedTimeout时间,则强制归还连接到连接池中。 -->
<property name="removeAbandoned" value="true" />
<!-- 超时时间,秒 -->
<property name="removeAbandonedTimeout" value="80"/>
<!-- 关闭abanded连接时输出错误日志,这样出现连接泄露时可以通过错误日志定位忘记关闭连接的位置 -->
<property name="logAbandoned" value="true" />
<!-- 根据自身业务及事务大小来设置 -->
<property name="connectionProperties"
value="oracle.net.CONNECT_TIMEOUT=2000;oracle.jdbc.ReadTimeout=10000"></property>
<!-- 打开PSCache,并且指定每个连接上PSCache的大小,Oracle等支持游标的数据库,打开此开关,会以数量级提升性能,具体查阅PSCache相关资料 -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="20" />
<!-- 配置监控统计拦截的filters -->
<!-- <property name="filters" value="stat,slf4j" /> -->
<property name="proxyFilters">
<list>
<ref bean="log-filter" />
<ref bean="stat-filter" />
</list>
</property>
<!-- 配置监控统计日志的输出间隔,单位毫秒,每次输出所有统计数据会重置,酌情开启 -->
<property name="timeBetweenLogStatsMillis" value="120000" />
</bean>
解释
spring:
datasource:
url: jdbc:h2:mem:recommend
username: sa
password:
##
# 设置数据源类型为 DruidDataSource
##
type: com.alibaba.druid.pool.DruidDataSource
druid:
##
# 配置初始化大小、最小、最大连接池数量
# - min-idle:池中维护的最小空闲连接数,默认为 0 个
# - max-active:池中最大连接数,包括闲置和使用中的连接,默认为 8 个;推荐配置:20,多数场景下 20 已完全够用,当然这个参数跟使用场景相关性很大,一般配置成正常连接数的 3~5 倍。
##
initial-size: 5
min-idle: 10
max-active: 20
##
# 参数表示是否对空闲连接保活,布尔类型。
#
# 那么需要保活连接,是不是将 keepAlive 配置成 true 就完事了呢?
# 虽然 true 的确是开启了保活机制,但是应该保活多少个,心跳检查的规则是什么,这些都需要正确配置,否则还是可能事与愿违。
# 这里需要了解几个相关的参数:minIdle 最小连接池数量,连接保活的数量,空闲连接超时踢除过程会保留的连接数(前提是当前连接数大于等于 minIdle),其实 keepAlive 也仅维护已存在的连接,而不会去新建连接,即使连接数小于 minIdle;
# minEvictableIdleTimeMillis 单位毫秒,连接保持空闲而不被驱逐的最小时间,保活心跳只对存活时间超过这个值的连接进行;
# maxEvictableIdleTimeMillis 单位毫秒,连接保持空闲的最长时间,如果连接执行过任何操作后计时器就会被重置(包括心跳保活动作);
# timeBetweenEvictionRunsMillis 单位毫秒,Destroy 线程检测连接的间隔时间,会在检测过程中触发心跳。保活检查的详细流程可参见源码 com.alibaba.druid.pool.DruidDataSource.DestroyTask,其中心跳检查会根据配置使用 ping 或 validationQuery 配置的检查语句。
#
# 推荐配置:如果网络状况不佳,程序启动慢或者经常出现突发流量,则推荐配置为 true;
##
keep-alive: true
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 600000
max-evictable-idle-time-millis: 900000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 2000
##
# 配置获取连接等待超时的时间
#
# 推荐配置:
# - 内网(网络状况好)800;
# - 网络状况不是特别好的情况下推荐大于等于 1200,因为 tcp 建连重试一般是 1 秒;
##
max-wait: 800
##
# 可以配置 connectTimeout 和 socketTimeout,它们的单位都是毫秒,这两个参数在应对网络异常方面非常重要。
# - connectTimeout 配置建立 TCP 连接的超时时间;
# - socketTimeout 配置发送请求后等待响应的超时时间;
# 这两个参数也可以通过在 jdbc url 中添加 connectTimeout=xxx&socketTimeout=xxx 的方式配置,试过在 connectinoProperties 中和 jdbc url两个地方都配置,发现优先使用 connectionProperties 中的配置。
# 如果不设置这两项超时时间,服务会有非常高的风险。现实案例是在网络异常后发现应用无法连接到 DB,但是重启后却能正常的访问 DB。因为在网络异常下 socket 没有办法检测到网络错误,这时连接其实已经变为“死连接”,如果没有设置 socket 网络超时,连接就会一直等待 DB 返回结果,造成新的请求都无法获取到连接。
#
# 推荐配置:socketTimeout=3000;connectTimeout=1200
##
connect-properties: socketTimeout=3000;connectTimeout=1200
##
# 用于检测连接是否有效的 SQL 语句
##
validation-query: select 1
##
# 申请连接的时候检测,如果空闲时间大于 timeBetweenEvictionRunsMillis,执行 validationQuery 检测连接是否有效
##
test-while-idle: true
##
# 申请连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能
##
test-on-borrow: false
##
# 归还连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能
##
test-on-return: false
##
# 通过限制达到一定使用次数后断开重连,使得多个服务器间负载更均衡
##
phy-max-use-count: 1000
chat
mysql 最佳配置
以下是 Alibaba Druid 连接 MySQL 数据库的最佳实践配置,以 YAML 格式呈现,并附带每个配置属性的解释和原因:
druid:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mydatabase?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
username: myuser
password: mypassword
# 初始化时连接池的大小
initial-size: 5
# 连接池的最小空闲连接数
min-idle: 5
# 连接池的最大活跃连接数
max-active: 20
# 获取连接时最大等待时间
max-wait: 60000
# 用于检测空闲连接的 SQL 查询语句
validation-query: SELECT 1
# 是否在获取连接时验证连接
test-on-borrow: true
# 是否在归还连接时验证连接
test-on-return: false
# 是否在连接空闲时验证连接
test-while-idle: true
# 配置间隔多久进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 300000
# 配置连接在池中最大生存的时间,单位是毫秒
max-evictable-idle-time-millis: 900000
# 打开PSCache,并且指定每个连接上PSCache的大小
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters,stat表示统计功能,wall表示防火墙
filters: stat,wall,log4j
# 合并多个DruidDataSource的监控数据
use-global-data-source-stat: true
# SQL执行时是否打印日志
log-slow-sql: true
# SQL执行超过多长时间就认为是慢SQL,单位毫秒
slow-sql-millis: 2000
# SQL日志是否需要格式化
connection-properties: druid.stat.slowSqlMillis=2000;druid.stat.logSlowSql=true
解释与原因
- driver-class-name:
com.mysql.cj.jdbc.Driver
- 使用 MySQL 官方驱动,推荐使用
com.mysql.cj.jdbc.Driver
,这是 MySQL Connector/J 8.0 版本之后的标准驱动类。
- 使用 MySQL 官方驱动,推荐使用
- url:
jdbc:mysql://localhost:3306/mydatabase?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
useSSL=false
:禁用 SSL 连接,除非有特别的安全需求。serverTimezone=UTC
:确保时区正确设置,避免由于时区问题引起的时间转换错误。useUnicode=true
和characterEncoding=UTF-8
:确保支持 UTF-8 字符集,避免字符集转换问题。
- initial-size:
5
- 初始化时创建 5 个连接,这样在应用启动时可以更快响应请求。
- min-idle:
5
- 保持 5 个最小空闲连接,确保在连接池空闲时仍有足够的连接来响应请求。
- max-active:
20
- 最大活动连接数设置为 20,这个数值可以根据应用的负载情况调整,以平衡性能与资源消耗。
- max-wait:
60000
- 获取连接的最大等待时间为 60 秒,如果超过这个时间仍无法获取连接,则抛出异常,避免无限制等待。
- validation-query:
SELECT 1
- 用于检测数据库连接是否有效。
SELECT 1
是一个非常轻量级的查询。
- 用于检测数据库连接是否有效。
- test-on-borrow:
true
- 在每次从连接池获取连接时验证连接的有效性,保证返回的连接是可用的。
- test-on-return:
false
- 归还连接时不进行验证,可以减少不必要的性能开销。
- test-while-idle:
true
- 在连接空闲时进行验证,避免长时间空闲连接失效。
- time-between-eviction-runs-millis:
60000
- 每 60 秒检查一次连接池中的空闲连接,并进行空闲连接的清理工作。
- min-evictable-idle-time-millis:
300000
- 连接在池中最小生存时间为 5 分钟,如果超过这个时间且连接空闲,则可以被清除。
- max-evictable-idle-time-millis:
900000
- 连接在池中最大生存时间为 15 分钟,超过这个时间无论是否空闲都可以被清除。
- pool-prepared-statements:
true
- 启用 PSCache(PreparedStatement Cache),提高预编译 SQL 的执行效率。
- max-pool-prepared-statement-per-connection-size:
20
- 每个连接最多缓存 20 个 PreparedStatement,合理的缓存大小可以减少重复解析和编译 SQL 的开销。
- filters:
stat,wall,log4j
- 启用 Druid 的监控、SQL 防火墙和日志功能,
stat
用于统计监控,wall
用于防止 SQL 注入,log4j
用于记录 SQL 日志。
- 启用 Druid 的监控、SQL 防火墙和日志功能,
- use-global-data-source-stat:
true
- 启用全局数据源的统计信息合并,方便统一管理和监控。
- log-slow-sql:
true
- 启用慢 SQL 日志记录,便于发现和优化执行较慢的 SQL 语句。
- slow-sql-millis:
2000
- 将 SQL 执行时间超过 2 秒定义为慢 SQL,适当调整这个值可以更好地捕捉性能瓶颈。
- connection-properties:
druid.stat.slowSqlMillis=2000;druid.stat.logSlowSql=true
- 额外的连接属性,用于配置 Druid 的慢 SQL 日志输出,进一步增强监控能力。
此配置主要是为了在性能和稳定性之间取得平衡,同时提供足够的监控和日志功能,便于后续维护和优化。
参考资料
https://www.cnblogs.com/yeahwell/p/9252931.html
https://www.cnblogs.com/wuyun-blog/p/5679073.html
https://y0ngb1n.github.io/a/best-practice-samples-datasource-alibaba-druid.html