前言

在复杂的业务场景中,我们经常需要使用多数据源来满足不同的数据访问需求。Dynamic Datasource 为我们提供了一种灵活切换不同数据源的解决方案。但是多数据源配置连接池 以及说明文档都是收费的。 本篇博文将详细介绍如何配置和优化 Dynamic Datasource 的连接池,包括 Druid 和 HikariCP,以及如何根据项目需求进行选择。

连接池配置

连接池是数据库连接管理的核心组件,它可以显著提高数据库操作的性能。以下是使用 Dynamic Datasource 配置连接池的详细步骤:

选择连接池实现:

Druid:阿里巴巴开源的数据库连接池,监控功能强大,配置灵活。
HikariCP:性能卓越,是当前市面上最快的连接池之一。

配置示例:

特此说明 如果配置配到了 spring.datasource.dynamic 下 druid 或者 hikari
这表示这个配置将作用于 dynamic 的所有数据源

在 application.yml 中配置连接池参数,以下为 Druid 和 HikariCP 的配置示例。

spring:   
  datasource:
    dynamic:
      # 全局配置的hikari 或druid
      # hikari 官方文档
      hikari:
         # 最小空闲数量
         min-idle: 10
         # 最小空闲数量
         minimumIdle:
         # 连接池最大数量
         max-pool-size: 100
         # 连接池最大数量
         maximum-pool-size:
         # 连接超时时间
         connectionTimeout:
         # 校验超时时间
         validationTimeout:
         # 空闲超时时间
         idleTimeout:
         # 此属性控制在记录指示可能的连接泄漏的消息之前连接可以离开池的时间量。值为0表示关闭泄漏检测。启用泄漏检测的最低可接受值是2000(2秒)。默认值:0
         leakDetectionThreshold:
         # 此属性控制池中连接的最大生存期 值为0表示没有最大生存期(无限生存期),当然取决于idleTimeout设置。最小允许值为30000ms(30秒)。默认值:1800000(30分钟)
         maxLifetime:
         # 初始化失败超时时间 即 到了指定时间还没初始化完成就算失败
         initializationFailTimeout:
         # 连接初始化SQL
         connectionInitSql:
         # 连接查询测试SQL
         connectionTestQuery:
         # 数据源类名
         dataSourceClassName: com.zaxxer.hikari.HikariDataSource
         dataSourceJndiName:
         # 事务隔离级别名称
         transactionIsolationName:
         # 自动提交
         isAutoCommit:
         # 是否只读
         isReadOnly:
         # 是否隔离内部查询
         isIsolateInternalQueries:
         # 是否注册 mbean
         isRegisterMbeans:
         # 是否允许pool 挂起
         isAllowPoolSuspension:
         # 存活时间
         keepaliveTime:
       druid:
         # 官方文档: https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8
         # 初始化数量 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
         initialSize: 50
         # 最大存活数量
         maxActive: 50
         # 最小空闲数量==>最小连接池数量
         minIdle: 20
         # 配置获取连接等待超时的时间
         maxWait:
         # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
         timeBetweenEvictionRunsMillis:
         # 配置间隔多久才进行日志统计,单位是毫秒
         timeBetweenLogStatsMillis:
         # 统计SQL最大数量
         statSqlMaxSize:
         # 配置一个连接在池中最小生存的时间,单位是毫秒
         minEvictableIdleTimeMillis:
         # 配置一个连接在池中最大生存的时间,单位是毫秒
         maxEvictableIdleTimeMillis:
         # 是否自动提交
         defaultAutoCommit:
         # 是否只读
         defaultReadOnly:
         # 默认事务隔离级别
         defaultTransactionIsolation:
         # 连接空闲测试
         testWhileIdle:
         # 当获取连接测试
         testOnBorrow:
         # 当归还连接测试
         testOnReturn:
         # 验证查询SQL
         validationQuery:
         # 验证查询超时时间
         validationQueryTimeout:
         # 使用全局数据源统计
         useGlobalDataSourceStat:
         # 异步初始化
         asyncInit:
         # 配置监控统计拦截的filters
         filters: stat
         clearFiltersEnable:
         # 重置统计开关
         resetStatEnable:
         notFullTimeoutRetryCount:
         # 最大等待线程数量
         maxWaitThreadCount:
         # 快速失败
         failFast:
         phyTimeoutMillis:
         # 保持连接开关 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。
         keepAlive:
         # ps pool开关
         poolPreparedStatements:
         initVariants:
         initGlobalVariants:
         # 使用非公平锁
         useUnfairLock:
         # socket读取超时 kill
         killWhenSocketReadTimeout:
         # 每个连接 最大ps 池数量
         maxPoolPreparedStatementPerConnectionSize:
         # 共享ps
         sharePreparedStatements:
         # 连接错误重试次数
         connectionErrorRetryAttempts:
         # 配置获取锁失败多少次 中断
         breakAfterAcquireFailure:
         removeAbandoned:
         removeAbandonedTimeoutMillis:
         # 查询超时时间
         queryTimeout:
         # 事务查询超时时间
         transactionQueryTimeout:
         # 连接超时时间
         connectTimeout:
         # socket 连接超时时间
         socketTimeout:
      datasource:
        ds1:
          url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
          #type: com.zaxxer.hikari.HikariDataSource
          type: com.alibaba.druid.pool.DruidDataSource
          #注意hikari和druid选择一个使用
          # hikari 官方文档
          hikari:
            ## 与上述全局 hikari 配置相同
          druid:
            #@ 与上述全局 druid 配置相同
        ds2:
          url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver

配置说明

HikariCP:

min-idle:连接池中最小空闲连接数量。
max-pool-size:连接池最大连接数量。
connection-timeout:连接超时时间。
validation-timeout:验证超时时间。
idle-timeout:空闲超时时间。
leak-detection-threshold:连接泄露检测阈值。
max-lifetime:连接最大存活时间。

Druid:

initial-size:初始化时建立的连接数量。
max-active:连接池最大连接数量。
min-idle:连接池中的最小空闲连接数量。
max-wait:获取连接最大等待时间。
time-between-eviction-runs-millis:检测连接间隔时间。
min-evictable-idle-time-millis:连接最小空闲时间。
validation-query:检测连接有效性的SQL。
filters:监控和防御插件。

文档资料

官方文档: 点我
github 主页: 点我

最佳实践

性能调优:

根据应用的负载和数据库性能,合理配置连接池大小。
启用连接泄露检测,及时发现并修复连接泄露问题。

实时监控:

使用监控工具(如 Prometheus、Zabbix)监控数据库连接池状态,包括活跃连接数、等待连接数、连接池利用率等。

性能基准测试:

使用工具(如 JMeter、LoadRunner)模拟数据库操作,测试连接池的性能表现。

慢查询日志分析:

配置并分析慢查询日志,找出性能瓶颈并进行优化。

安全最佳实践

密码加密

对数据库连接使用的密码进行加密,可以使用第三方库(如 Jasypt)来实现。

访问控制:

严格控制数据库访问权限,遵循最小权限原则。

定期安全审计:

定期进行数据库安全审计,检查潜在的安全风险。

监控和日志:

启用连接池监控,实时监控数据库连接状态。
配置慢查询日志,及时发现并优化慢查询。

总结

通过合理配置连接池参数,我们可以有效提高数据库操作的性能和稳定性。Druid 和 HikariCP 都是优秀的连接池实现,可以根据项目需求和团队熟悉度进行选择。


good day !!!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐