1. 当Druid连接超时引发的血案上周排查一个线上问题接口日志里频繁出现Connection timed out错误前端页面直接显示504 Gateway Timeout。打开Druid监控面板一看活跃连接数曲线像过山车一样上蹿下跳。这种场景相信不少朋友都遇到过——当SQL查询复杂度突然增加或者数据库服务器负载飙升时原本运行良好的系统就会开始报连接超时错误。这里有个关键认知误区要纠正Druid的连接超时和HTTP请求超时是两码事。HTTP超时通常由Nginx或Tomcat控制而Druid的超时发生在TCP/IP协议栈层面。举个例子你的接口设置了10秒超时但Druid默认连接超时只有30秒不同版本可能有差异当网络抖动或数据库压力大时这个时间可能根本不够用。2. 核心配置参数详解2.1 connectTimeout与socketTimeout的区别很多开发者容易混淆这两个参数我用快递员送包裹的场景来解释connectTimeout相当于快递员从驿站出发到你家门口的时间限制。对应到数据库连接就是Druid客户端与MySQL服务器建立TCP连接的最大等待时间socketTimeout相当于快递员在你家门口等你签收包裹的等待时间。对应到数据库操作就是SQL语句执行的最大允许时长在Druid 1.2.12版本中这两个参数需要显式配置才会生效。典型的生产环境配置应该是这样的spring: datasource: druid: connectTimeout: 30000 # 连接建立超时30秒 socketTimeout: 600000 # 查询执行超时10分钟 validationQuery: SELECT 1 testWhileIdle: true2.2 版本兼容性陷阱我在实际项目中踩过一个坑同样的配置在测试环境正常上生产后却失效。后来发现测试环境用的是Druid 1.1.10而生产环境是1.2.12。关键差异在于版本范围行为差异1.2.0超时参数继承驱动默认值≥1.2.0必须显式声明connect/socketTimeout建议在pom.xml中固定Druid版本dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-starter/artifactId version1.2.16/version /dependency3. 配置不生效的常见原因3.1 前缀匹配问题原始文章提到的配置前缀问题非常典型。Spring Boot的配置解析就像玩拼图必须严丝合缝。比如这样的配置druid: url: jdbc:mysql://localhost:3306/db connectTimeout: 60000对应的配置类必须是ConfigurationProperties(prefix druid) public class DruidProperties { private String url; private int connectTimeout; // getters setters }我曾经因为把前缀写成spring.druid而浪费了两小时排查时间。建议在应用启动时增加参数--debug观察输出的Configuration Properties Report确认配置是否被正确加载。3.2 连接池参数联动单独设置超时参数有时还不够需要配合其他连接池参数druid: max-active: 100 # 最大连接数 max-wait: 60000 # 获取连接等待超时时间 min-idle: 10 # 最小空闲连接 filters: stat,wall # 启用监控统计和防御SQL注入特别是max-wait参数当连接池耗尽时它决定了应用等待获取连接的最长时间。如果设置过小可能在流量突增时导致大量获取连接超时。4. 高级调优技巧4.1 动态超时策略对于读写分离场景可以针对不同SQL类型设置差异化超时DruidDataSource ds new DruidDataSource(); ds.setConnectTimeout(30000); ds.setSocketTimeout(60000); ds.setQueryTimeout(30000, 60000); // 读30秒写60秒4.2 监控集成建议开启Druid内置的监控功能在配置类中添加Bean public ServletRegistrationBeanStatViewServlet druidServlet() { ServletRegistrationBeanStatViewServlet reg new ServletRegistrationBean(); reg.setServlet(new StatViewServlet()); reg.addUrlMappings(/druid/*); reg.addInitParameter(loginUsername, admin); reg.addInitParameter(loginPassword, 123456); return reg; }通过http://localhost:8080/druid访问监控台重点关注活跃连接数峰值执行时间分布直方图慢SQL记录4.3 连接泄漏检测在测试环境可以开启连接泄漏检测druid: remove-abandoned: true remove-abandoned-timeout: 300 # 5分钟未关闭的连接视为泄漏 log-abandoned: true这能帮助发现未正确关闭Connection或Statement的代码位置。5. 典型异常处理5.1 连接超时异常当看到com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure时建议检查数据库服务器防火墙设置网络延迟情况可用ping/telnet测试Druid配置的connectTimeout是否足够5.2 查询超时异常遇到java.sql.SQLTimeoutException: Query timeout时检查socketTimeout设置使用EXPLAIN分析慢查询考虑添加适当的数据库索引有个小技巧在测试环境可以临时设置druid.queryTimeout1快速发现潜在的性能瓶颈。6. 生产环境建议经过多个项目的实践验证推荐以下生产级配置模板spring: datasource: druid: url: jdbc:mysql://db-host:3306/prod_db?useSSLfalse username: app_user password: ${DB_PASSWORD} initial-size: 5 min-idle: 5 max-active: 50 max-wait: 10000 connect-timeout: 3000 socket-timeout: 30000 filters: stat,wall,slf4j filter: stat: slow-sql-millis: 1000 log-slow-sql: true use-global-data-source-stat: true time-between-eviction-runs-millis: 60000 min-evictable-idle-time-millis: 300000关键点在于连接数按实际负载调整建议初始值CPU核心数×2超时时间根据业务特点设定批量作业需延长必须启用监控过滤器定期回收空闲连接time-between-eviction-runs-millis最后提醒所有超时参数的单位都是毫秒配置时千万别少写几个零。曾经有同事把30000写成300结果半夜被报警叫起来处理故障。