动态数据源 是一种在运行时动态切换数据库连接的技术,常用于支持以下场景

  1. 读写分离:将写操作指向主库,读操作指向从库
  2. 多租户模式:不同租户使用不同的数据库
  3. 分库分表:根据规则动态选择目标库

动态数据源的作用

  1. 提高系统性能:

    • 通过读写分离,将读操作分散到多个从库,降低主库压力。
  2. 支持多租户架构

    • 根据租户 ID 动态选择数据库,实现数据隔离。
  3. 分库分表支持:

    • 根据分片规则,动态选择目标数据库
  4. 灵活性:

    • 无需固定绑定某个数据源,可以根据业务需求动态切换。

动态数据源的底层原理

动态数据源的实现依赖于 Spring 的 AbstractRoutingDataSource 类。其原理如下:

  1. 多数据源配置:

    • 在应用中定义多个数据源,并将其注入 AbstractRoutingDataSource。
  2. 动态数据源选择:

    • AbstractRoutingDataSource 会根据上下文中设置的数据源标识(key)动态决定使用哪个数据源
  3. ThreadLocal 存储数据源标识

    • 使用ThreadLocal在当前线程中存储数据源标识,确保每次数据库操作都使用正确的数据源
  4. 核心方法

    • AbstractRoutingDataSource 的 determineCurrentLookupKey() 方法,会根据上下文返回当前使用的数据源标识

Hikari与Druid

HikariCP和Druid是两种常见的数据库连接池实现,它们在Java应用中用于管理高效的数据库连接,提升性能。

HikariCP

  • 简介

    • HikariCP是一个轻量级,高性能的JDBC连接池,被广泛认为是目前最快的Java数据库连接池之一。它注重性能和可靠性,适用于高并发场景。
  • 特点

    • 性能优异

      • Hikari以极低的开销和快速的响应著称
      • 对性能的优化非常深入,如连接池初始化速度块,查询响应低延迟等
    • 轻量级

      • 源代码精简,依赖少
      • 适合需要高度优化的小型服务器或者微服务架构
    • 简单适用

      • 配置项目少,默认配置已经非常高效
      • 易集成到SpringBoot等框架上
    • 高可靠性

      • 高效的泄漏检测和故障恢复机制
      • 多种内置的监控指标
  • 优点

    • 性能极高,特别适合低延迟,高吞吐的环境
    • 易用性强,开箱即用
    • 活跃维护,广泛使用与社区
  • 缺点

    • 自定义功能少,相较于Druid较少的内置的扩展工具
    • 偏向轻量化,可能需要更多外部的工具支持监控和调试

HiKariCP核心功能

  • 连接池的管理

    • 提供最大/最小连接数的动态管理
    • 闲置连接清理机制,减少资源的浪费
  • 快速失败机制

    • 启动时立刻检测数据连接是否可用,避免运行期才能发现问题
  • 异步初始化

    • 支持线程池异步初始化,提升启动速度
  • 连接池泄漏检测

    • 可以设置超时时间,自动检测未归还的连接并警告。
  • 高效的数据结构

    • 使用队列 + 锁机制,最大化并发性能

核心参数

  1. 最大连接数(默认10):连接池中的最大连接数(包括空闲连接)。
  2. 最小连接数(默认10):最小空闲连接数,当空闲连接不足时,会新建连接。
  3. 连接超时时间(30s):获取连接的超时时间,超时会抛出异常。
  4. 最大空闲时间(10ms):空闲连接的最大存活时间,超时则被清理。
  5. 连接的最大存活时间(30ms):即使空闲也会在超过此时间后重建连接
  6. 验证连接的超时时间(5s):验证连接的超时时间。
  7. 连接泄露检测时间(0【禁用】)超过此时间未关闭的连接将记录日志。

Druid

  • 简介

    • Druid 是阿里巴巴开源的数据库连接池,同时具备强大的监控、扩展和 SQL 分析功能,特别适合复杂场景的企业级应用。
  • 特点

    • 功能丰富

      • 提供SQL监控的功能,可以记录慢查询,SQL执行计划
      • 支持数据加密,过滤器链等高级功能
    • 良好的兼容性

      • 可以兼容更多的数据库,包括 MySQL、PostgreSQL、Oracle 等
      • 内置对多种数据库驱动的优化
    • 灵活的扩展能力

      • 内置丰富的扩展功能,如连接过滤器、动态数据源切换等
      • 支持 SQL 防火墙、防止 SQL 注入。
  • 监控能力

    • 提供WebUI,可以查看连接池的状态,SQL执行计划
  • 优点

    • 功能全面,适合高级管理和监控的企业应用
    • 社区活跃,在国内有广泛支持和使用
    • 易于扩展,适合复杂业务场景。
  • 缺点

    • 性能略逊于HikariCP,尤其在高并发的情况下
    • 配置复杂度相对较高。
    • 更大的内存占比

SpringBoot集成

HikariCP(默认连接池)
Spring Boot 默认集成 HikariCP,无需额外配置:

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root

Druid(手动集成)

需要引入依赖并手动配置:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>最新版本号</version>
</dependency>

配置 application.yml:

spring:
  datasource:
    druid:
      url: jdbc:mysql://localhost:3306/test
      username: root
      password: root
      initialSize: 5
      maxActive: 20
      filters: stat,wall

数据库连接池的核心参数

  1. 最小连接数(Minimum idle Connections):数据库连接池在初始化时会创建的最小空闲连接数,用于应对基础负载。
  2. 最大连接数(Maximum Pool Size):数据库连接池允许的最大连接数,限制同时与数据库交互的最大连接数量
  3. 空闲连接最大存活时间(idle Timeout):连接池中的空闲连接在多长时间后会被回收,避免资源浪费
  4. 最大等待时间(Connection Timeout):当所有连接都被占用时,新请求获取连接的最长等待时间。如果超时,则抛出异常
  5. 初始化连接数(Inital Connections):数据库连接池初始化时创建的连接数
  6. 阻塞策略(Blocking Queue Behavior):当连接用尽的时候,数据库连接池会决定如何处理新的请求

数据库连接池的阻塞策略

  1. 抛出异常(Fail Fast):超过等待时间后直接抛出异常,提示资源不足
  2. 阻塞等待(Block):请求进入阻塞队列,直到有可用的连接为止
  3. 丢弃策略(Discard Oldest):丢弃最早的请求(如果丢列支持)
  4. 创建新连接(Dymanic Growth):动态增加连接数(如果配置允许),可能超出最大连接数

典型应用中的参数设置建议

  1. 小型应用:最小连接数=1,最大连接数=10,等待时间较长。
  2. 大型应用:增加最大连接数(如50或100),适当缩短空闲连接时间

爱跑步的猕猴桃
1 声望0 粉丝