1. 为什么需要ShardingSphere-JDBC与Druid的整合
在微服务架构中,数据库访问层的性能与可靠性直接影响整个系统的稳定性。我遇到过不少项目,初期随便配置个连接池就上线,等到用户量上来后,连接泄漏、慢SQL堆积、监控缺失等问题集中爆发。这时候Druid的连接池监控能力和ShardingSphere的分库分表能力就成了救命稻草。
Druid作为阿里开源的数据库连接池,最吸引我的就是它的监控功能。它能实时统计SQL执行情况、连接池状态,还能记录慢查询。而ShardingSphere-JDBC作为分库分表中间件,能让应用像操作单库单表一样操作分片数据。两者结合,既能解决数据量大时的扩展性问题,又能保障数据库访问的可观测性。
不过在实际整合时,我发现网上大多数教程都存在两个问题:一是配置冗余,同样的参数在每个数据源重复定义;二是排除Druid自动配置后监控页面失效。这就像买了辆跑车却拆掉了仪表盘,完全失去了Druid的核心价值。
2. 基础环境搭建与依赖配置
2.1 版本选择与依赖引入
先说说版本兼容性这个坑。去年我在一个金融项目中使用ShardingSphere 5.0.0-alpha时,还能用common配置项简化配置。但升级到5.1.1后发现这个功能被移除了,必须每个数据源单独配置。所以建议大家先确认版本:
<!-- 当前稳定版 --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId> <version>5.3.2</version> </dependency> <!-- Druid连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.16</version> </dependency>2.2 必须的排除项配置
由于ShardingSphere要接管数据源管理,我们需要排除Druid的自动配置:
spring: autoconfigure: exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure这个配置会带来一个典型问题:Druid的监控页面/druid会404。我当初排查了半天才发现,排除自动配置的同时把监控Servlet的注册也禁用了。就像关掉了水龙头还想接水,显然行不通。
3. 优雅的公共配置方案
3.1 使用common配置项减少重复
在支持common配置的版本中,可以这样优化配置:
spring: shardingsphere: datasource: common: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver initial-size: 5 max-active: 20 filters: stat,wall names: ds0,ds1 ds0: url: jdbc:mysql://localhost:3306/db0 ds1: url: jdbc:mysql://localhost:3306/db1这样所有数据源共享连接池参数,维护起来方便多了。不过要注意,5.1.1+版本需要改为:
spring: shardingsphere: datasource: ds0: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver initial-size: 5 url: jdbc:mysql://localhost:3306/db0 ds1: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver initial-size: 5 url: jdbc:mysql://localhost:3306/db13.2 关键参数调优建议
经过多次压测,我总结出几个关键参数:
- initial-size:建议设置为
CPU核心数*2,避免启动时频繁创建连接 - max-active:不要超过数据库的
max_connections限制 - timeBetweenEvictionRunsMillis:生产环境建议30000ms(30秒)
- minEvictableIdleTimeMillis:建议180000ms(3分钟)
特别提醒:Oracle需要设置validationQuery: SELECT 1 FROM DUAL,而MySQL可以不用。
4. 监控功能恢复的终极方案
4.1 手动注册Servlet的局限
网上常见的解决方案是手动注册Servlet:
@Bean public ServletRegistrationBean druidServlet() { return new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); }但这种方式需要硬编码登录账号密码,非常不优雅。我在金融项目中就因为这种配置被安全团队开了漏洞单。
4.2 更优雅的自动配置方案
其实Druid本身提供了StatViewServlet的自动配置,只是被我们排除了。解决方法是从源码中找到这个配置类:
@Configuration @ConditionalOnClass(DruidDataSourceAutoConfigure.class) @EnableConfigurationProperties(DruidStatProperties.class) @Import({ DruidSpringAopConfiguration.class, DruidStatViewServletConfiguration.class, DruidWebStatFilterConfiguration.class }) public class DruidShardingConfig { }然后在application.yml中就可以使用标准配置了:
spring: datasource: druid: stat-view-servlet: enabled: true login-username: admin login-password: admin@123 web-stat-filter: enabled: true这样既保持了配置的集中管理,又恢复了完整的监控功能。监控页面的访问控制也更安全,支持IP白名单配置。
5. 生产环境中的避坑指南
5.1 多数据源下的特殊问题
在电商项目中,我们遇到过这样的问题:某个从库的max-active设置过小,导致大促时连接耗尽。但由于使用了common配置,所有数据源参数被强制统一。最终解决方案是:
ds0: max-active: 50 # 主库设置较大连接数 ds1: max-active: 20 # 从库可以适当减小5.2 监控页面的安全加固
千万不要用默认账号密码!我见过太多因为弱密码导致数据库被黑的案例。建议:
- 密码复杂度至少包含大小写字母+数字+特殊字符
- 启用IP白名单限制
- 定期轮换密码
spring: datasource: druid: stat-view-servlet: deny: 192.168.1.100 # 黑名单 allow: 10.0.0.1,127.0.0.1 # 白名单5.3 慢SQL监控与优化
Druid的慢SQL记录功能非常实用:
spring: datasource: druid: filter: stat: slow-sql-millis: 1000 log-slow-sql: true配合connectionProperties参数,还能实现SQL合并统计:
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5006. 完整配置参考与使用建议
6.1 适用于5.0.0-alpha的配置
spring: shardingsphere: datasource: common: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver filters: stat,wall max-active: 20 initial-size: 5 names: ds0,ds1 ds0: url: jdbc:mysql://localhost:3306/db0 ds1: url: jdbc:mysql://localhost:3306/db1 datasource: druid: stat-view-servlet: enabled: true login-username: admin login-password: Str0ngP@ss6.2 适用于5.3.2的最新配置
spring: shardingsphere: datasource: ds0: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db0 filters: stat,wall max-active: 20 ds1: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db1 max-active: 15 # 可以差异化配置 datasource: druid: web-stat-filter: enabled: true stat-view-servlet: enabled: true login-username: monitor login-password: M0nit0r@2023实际项目中,建议将密码等敏感信息放在单独的application-secret.yml中,并通过-D参数指定配置文件位置,避免密码泄露。