Spring Boot 3 多数据源整合 Druid:监控页面与控制台 SQL 日志配置实战

6 阅读4分钟

踩坑3天,配置50+次,终于让监控页面亮起来、SQL日志哗哗输出!
本文完整记录 Spring Boot 3.2 + JDK 17 环境下,多数据源集成 Druid 的实战全过程,含避坑指南与生产建议。


🌟 为什么这次“终于搞定”?

  • Spring Boot 3 专属适配:包名从 javaxjakarta,普通 Druid Starter 直接失效
  • 多数据源精准监控:主库/从库 SQL 独立统计,不再“只见其一”
  • 控制台 SQL 带参输出:参数值、耗时、连接ID 清晰可见(开发调试神器)
  • 安全加固:监控页登录认证 + IP 白名单 + 生产环境开关

🔧 一、环境与依赖(关键!)

<!-- pom.xml 核心依赖 -->
<properties>
    <java.version>17</java.version>
    <druid.version>1.2.20</druid.version> <!-- 必须 >=1.2.11 -->
</properties>

<dependencies>
    <!-- Spring Boot 3 Web + JDBC -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    
    <!-- ✨ 重点:Druid Spring Boot 3 专用 Starter -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-3-starter</artifactId>
        <version>${druid.version}</version>
    </dependency>
    
    <!-- MySQL 驱动(Jakarta 兼容版) -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

💡 血泪教训
❌ 错误:druid-spring-boot-starter(仅支持 SB2)
✅ 正确:druid-spring-boot-3-starter(官方 2023 年发布)


📝 二、application.yml 配置(精华所在)

spring:
  # ===== 主数据源(标记 @Primary)=====
  datasource:
    primary:
      url: jdbc:mysql://localhost:3306/order_db?useSSL=false&serverTimezone=Asia/Shanghai
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver
      druid:
        initial-size: 5
        min-idle: 5
        max-active: 20
        # 🔑 SQL 日志核心配置(开发环境开启)
        filter:
          slf4j:
            enabled: true
            statement-log-enabled: true
            statement-executable-sql-log-enable: true # 输出带参数的SQL!
            statement-create-after-log-enabled: false
            statement-close-after-log-enabled: false
          stat:
            enabled: true
            log-slow-sql: true
            slow-sql-millis: 10
            merge-sql: true

    # ===== 从数据源 =====
    secondary:
      url: jdbc:mysql://localhost:3306/user_db?useSSL=false&serverTimezone=Asia/Shanghai
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver
      druid:
        # 配置同上,略...

# ===== Druid 全局监控配置 =====
druid:
  stat-view-servlet:
    enabled: true
    url-pattern: /druid/*
    login-username: admin
    login-password: StrongPass123! # ⚠️ 生产务必改!
    allow: 127.0.0.1,192.168.1.0/24 # IP白名单
    reset-enable: false
  web-stat-filter:
    enabled: true
    url-pattern: /*
    exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
  # 🌐 Spring Boot 3 必加:解决 Filter 注册问题
  aop-patterns: com.example.service.*

⚙️ 三、多数据源配置类(Java Config)

@Configuration
public class DataSourceConfig {

    // ===== 主数据源 =====
    @Primary
    @Bean(name = "primaryDataSource")
    @ConfigurationProperties("spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    // ===== 从数据源 =====
    @Bean(name = "secondaryDataSource")
    @ConfigurationProperties("spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    // ===== (可选)MyBatis 多数据源支持示例 =====
    @Bean
    @Primary
    public SqlSessionFactory primarySqlSessionFactory(
            @Qualifier("primaryDataSource") DataSource ds) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(ds);
        return factory.getObject();
    }
}

💡 关键点

  • 使用 DruidDataSourceBuilder.create().build() 确保 Druid 配置生效
  • @Primary 标记主数据源,避免自动注入冲突
  • 若用 JPA/Hibernate,需额外配置 EntityManagerFactory

🖨️ 四、控制台 SQL 日志配置(灵魂步骤!)

方案 A:application.yml(推荐)

logging:
  level:
    druid.sql.Statement: DEBUG   # 输出SQL语句+耗时
    druid.sql.Connection: DEBUG  # 连接创建/关闭
    druid.sql.ResultSet: DEBUG   # 结果集(按需)
  pattern:
    console: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"

方案 B:logback-spring.xml(精细控制)

<logger name="druid.sql.Statement" level="DEBUG" additivity="false">
    <appender-ref ref="CONSOLE"/>
</logger>
<logger name="druid.sql.Connection" level="DEBUG" additivity="false">
    <appender-ref ref="CONSOLE"/>
</logger>

控制台效果示例

14:23:18.451 [http-nio-8080-exec-3] DEBUG druid.sql.Statement 
- {conn-10005, pstmt-20008} executed. 8.23ms 
SELECT * FROM orders WHERE user_id = 1001

14:23:18.453 [http-nio-8080-exec-3] DEBUG druid.sql.Statement 
- {conn-10005, pstmt-20008} parameters: [1001]

🔒 生产环境提醒

  • 关闭 statement-executable-sql-log-enable 避免敏感数据泄露
  • 通过 Profile 控制:@Profile("dev") 仅开发环境开启日志

🌐 五、验证三连击

  1. 启动日志
    DruidDataSource - {dataSource-1} inited → 两个数据源均初始化成功

  2. 访问监控页
    http://localhost:8080/druid → 输入账号密码 → 查看:

    • 数据源监控:两个连接池状态独立显示
    • SQL监控:主库/从库 SQL 分开统计,含执行次数、最慢时间
    • URI监控:接口耗时一目了然
  3. 执行数据库操作
    控制台实时输出带参数的 SQL + 耗时(开发调试效率翻倍!)


🚫 六、高频踩坑指南(亲测有效)

问题现象根本原因解决方案
监控页 404用了 SB2 的 Druid Starterdruid-spring-boot-3-starter
只监控到1个数据源未为每个数据源启用 stat filteryml 中显式配置 druid.filter.stat.enabled=true
SQL 日志无参数未开 statement-executable-sql-log-enableyml 中开启 + 日志级别 DEBUG
Filter 未生效(SB3)Spring Boot 3 包名变更添加 druid.aop-patterns 配置
多数据源事务失效未指定 TransactionManager为每个数据源配置独立的 PlatformTransactionManager

💡 七、生产环境最佳实践

# application-prod.yml
druid:
  stat-view-servlet:
    enabled: false # ❌ 生产关闭监控页!或通过网关严格管控
  filter:
    slf4j:
      enabled: false # ❌ 关闭SQL日志
    wall:
      enabled: true  # ✅ 启用SQL防火墙防注入
      db-type: mysql
  • 安全加固:监控页通过 Nginx 做 IP 限制 + Basic Auth 双重认证
  • 日志脱敏:自定义 Filter 拦截敏感字段(如手机号、身份证)
  • 性能监控:对接 Prometheus + Grafana 做可视化大盘
  • 动态配置:通过 Nacos/Apollo 热更新连接池参数

🌈 结语

从“监控页404”到“SQL日志刷屏”,从“参数全是问号”到“带值可执行SQL”,每一步踩坑都是成长。Spring Boot 3 的生态迁移虽有阵痛,但清晰的架构和强大的社区支持终将带来更健壮的系统。


附:速查清单
✅ 依赖用 druid-spring-boot-3-starter
✅ 每个数据源 yml 配 filter.slf4j + filter.stat
✅ logging.level 指定 druid.sql.Statement=DEBUG
✅ 监控页配置 allow + 强密码
✅ 生产环境关闭 SQL 日志 + 监控页访问控制