Spring Boot这5个配置项默认值就是错的,高并发第1天就502
上个月帮一个团队做上线前的Code Review翻了12个Spring Boot项目有9个项目的核心配置项是默认的。开发用默认配置在本地跑得好好的扔到生产就炸——Tomcat线程数200不够、HikariCP连接池10个不够、Actuator全暴露被扫描、Druid慢SQL没人看。任何一个配置项单独看都不致命。但高并发场景下这些配置项中的任何一个缺失都会直接导致502。这不是配置调优的问题是配置有没有的问题。下面5项是Spring Boot上线前的最低配置项清单每一项都有血淋淋的案例。1Tomcat线程数默认200大促直接排队到超时事故场景某电商大促峰值QPS 3000服务从200线程的Tomcat里拿出400个线程处理请求——结果有300个请求在队列里等着排队超过2秒直接超时。监控显示Tomcat线程池使用率100%accept-count队列从50个满到500个。默认配置的问题# Spring Boot 2.x 默认值 server.tomcat.threads.max200 # 最大工作线程 server.tomcat.max-connections8192 # 最大连接数 server.tomcat.accept-count100 # 等待队列长度 server.tomcat.connection-timeout5s # 连接超时 # 大促场景200线程处理3000 QPS每个请求平均100ms # → 200 / 0.1 2000 QPS上限 # → 峰值3000 QPS直接超出40%正确配置按业务估算# 业务侧需求峰值QPS 3000平均响应时间 100ms # 最低线程数 3000 × 0.1 300个 # 建议值按峰值QPS × 平均RT的1.5倍配置留出30%buffer server.tomcat.threads.max500 # 峰值时段留buffer server.tomcat.min-spare-threads50 # 最小空闲线程避免冷启动排队 server.tomcat.max-connections10000 # 略大于Tomcat线程数 server.tomcat.accept-count200 # 队列不能太长太长等于502 server.tomcat.connection-timeout10s经验值Tomcat线程数 峰值QPS × 平均RT × 1.5。3000 QPS × 0.1s × 1.5 450个至少配到500。不要拍脑袋配200那是开发机的值。2HikariCP连接池默认10QPS超过50就排队事故场景某金融系统上线后白天正常一到晚上批量任务时段QPS从30涨到80HikariCP连接池使用率持续100%慢SQL数量从1条/小时涨到200条/小时。监控显示getConnection()等待时间从2ms涨到800ms。默认配置的问题# Spring Boot 2.x 默认值HikariCP spring.datasource.hikari.maximum-pool-size10 # 池大小 spring.datasource.hikari.minimum-idle10 # 最小空闲 spring.datasource.hikari.connection-timeout30000 # 30秒 spring.datasource.hikari.idle-timeout600000 # 10分钟 spring.datasource.hikari.max-lifetime1800000 # 30分钟 # 问题10个连接假设每个查询100ms # → 10 / 0.1 100 QPS上限 # → 超过100 QPS的请求开始等待连接 → 慢SQL正确配置按数据库能力估算# 先查数据库最大连接数show variables like max_connections; # 一般MySQL默认151个全部分给业务大概有120个可用 # 单实例应用池大小 ≤ 30留buffer给其他应用 # 多实例应用池大小 总可用连接数 / 实例数 - 5 spring.datasource.hikari.maximum-pool-size30 # 单实例不超过30 spring.datasource.hikari.minimum-idle10 # 保留10个空闲 spring.datasource.hikari.connection-timeout3000 # 3秒拿不到连接直接报错 spring.datasource.hikari.idle-timeout300000 # 5分钟回收空闲 spring.datasource.hikari.max-lifetime1200000 # 20分钟强制重建避免数据库单方面断开 spring.datasource.hikari.leak-detection-threshold30000 # 30秒未释放视为泄漏HikariCP官方建议池大小 ((核心数 × 2) 1) 个硬盘连接数但实际按数据库承载能力配更合理。MySQL默认151连接20个实例 × 30连接 600不行MySQL扛不住。单个应用连接池 ≤ 数据库max_connections的30%。3Actuator端点全暴露等于把数据库连接池监控送人事故场景某团队Actuator端点暴露在公网/actuator/env直接返回数据库密码、Redis密码、JWT密钥。安全扫描工具10秒扫到30分钟内被脱裤。事后复盘开发说我以为默认就是不暴露的实际上Spring Boot 2.x之后默认就暴露/actuator/health和/actuator/info而/actuator/*全暴露是开发本地配置的。默认配置的问题# Spring Boot 2.x 之后Actuator只暴露health和info # 但很多人为了方便会写 management.endpoints.web.exposure.include* # ⚠️ 全暴露 # 等于把下面这些全部开放到公网 # /actuator/env → 环境变量含数据库密码 # /actuator/configprops → 完整配置含明文密码 # /actuator/beans → 所有Bean # /actuator/mappings → 所有URL映射 # /actuator/threaddump → 线程栈含业务逻辑 # /actuator/heapdump → 完整内存镜像正确配置最小暴露原则# application.yml management: endpoints: web: exposure: include: health,info,metrics,prometheus # 只暴露监控需要的 exclude: env,configprops,beans,mappings,threaddump,heapdump endpoint: health: show-details: never # 不显示详细信息只返回UP/DOWN server: address: 127.0.0.1 # 关键Actuator只监听本地通过Prometheus从本地拉 # 或者放到内网端口不走主端口 management.server.port: 9090 management.server.address: 10.0.0.0/8 # 只允许内网访问Actuator的heapdump端点是最危险的——它返回完整JVM堆内存镜像里面有所有缓存的密码、用户token。绝对不能暴露在公网必须限制访问来源IP。4日志级别默认INFO生产环境全打就完了事故场景某团队从DEBUG切回INFO时漏改了一个第三方库的levelMyBatis的SQL日志每天打500MB一周后磁盘写满服务挂了。更极端的案例把整个Spring Framework的日志级别配成DEBUG单服务每天日志量8GB。默认配置的问题# Spring Boot默认root level INFO # 但很多团队没显式配导致 # 1. 业务代码的DEBUG也漏出来 # 2. 第三方库Spring/MyBatis/HikariCP全部INFO # 3. 大促期间日志量翻3-5倍 # MyBatis默认DEBUG把每条SQL参数都打出来 # HikariCP默认DEBUG把连接池状态都打出来 # Spring Web默认INFO把每次请求都打出来正确配置生产环境分级# application-prod.yml logging: level: root: INFO # 默认INFO com.example.business: INFO # 业务代码 org.springframework: WARN # Spring框架 org.mybatis: WARN # MyBatis关掉 com.zaxxer.hikari: WARN # HikariCP关掉 org.apache.tomcat: WARN # Tomcat关掉 file: name: /var/log/app/app.log max-size: 100MB # 单文件100MB max-history: 7 # 保留7天 total-size-cap: 10GB # 总大小不超过10GB生产环境业务代码INFO、第三方库全部WARN或OFF。业务级INFO 第三方WARN日志量能从500MB/天降到50MB/天。5Profile激活忘了指定配置文件全乱套事故场景某团队启动命令没指定profileSpring Boot默认加载application.yml直接连到了测试库的数据库。测试数据被生产服务读出来用户看到一堆测试账号运营群里炸了。修复花了2小时事故报告写了8页。默认配置的问题# 没有指定profile时Spring Boot只加载 application.yml # 而 application.yml 里通常写的是开发配置 # application.yml开发配置 spring: datasource: url: jdbc:mysql://192.168.1.100:3306/test_db username: dev_user password: dev_pass logging: level: com.example.business: DEBUG正确配置强制Profile# application.yml公共配置 spring: profiles: active: dev # 开发默认dev application: name: my-service # application-prod.yml生产配置 spring: datasource: url: jdbc:mysql://prod-db:3306/prod_db username: ${DB_USER} # 从环境变量读 password: ${DB_PASS} logging: level: com.example.business: INFO org.springframework: WARN生产环境启动时强制指定profile# K8s deployment env: - name: SPRING_PROFILES_ACTIVE value: prod # 强制proddev/staging都不会生效 # 启动命令 java -jar -Dspring.profiles.activeprod app.jar # 或者用环境变量 export SPRING_PROFILES_ACTIVEprod java -jar app.jar经验生产环境的启动命令必须显式指定profile并且profile配置必须和默认配置严格区分。配置文件结构建议application.yml公共 application-{profile}.yml环境特定profile从环境变量读不允许在代码里硬编码。5项配置速查表配置项默认值坑建议值不配的后果server.tomcat.threads.max200峰值QPS × 平均RT × 1.5高并发排队超时spring.datasource.hikari.maximum-pool-size10≤ DB max_connections × 30%连接池排队慢SQLmanagement.endpoints.web.exposure.includehealth,infohealth,info,metrics,prometheus数据库密码泄漏logging.level.rootINFOINFO 第三方库WARN日志爆炸磁盘写满spring.profiles.activedefault从环境变量注入prod配置错乱测试库上线这5项是Spring Boot上线前的最低必查项不是建议配置。任何一项缺失在生产环境高并发场景下都会直接暴露问题。配置项之间不冲突可以一次性全部加上。配置检查清单打印出来贴工位□ Tomcat线程数按QPS估算不小于500 □ HikariCP连接池按DB能力估算不小于20 □ Actuator端点最小暴露不包含env/heapdump □ 生产日志级别业务INFO 第三方WARN □ 启动命令显式指定prod profile □ 配置文件分环境application-{profile}.yml □ 敏感配置从环境变量读不用明文密码 □ 配置变更记录到Git不直接在服务器改Spring Boot配置检查飞算JavaAI帮你30秒扫完这5项配置在Spring Boot项目里非常容易遗漏——特别是HikariCP连接池大小和Actuator端点暴露靠人工Code Review经常漏掉。飞算JavaAI的代码审查器可以自动扫描项目中的application.yml、application.properties、logback.xml等配置文件检查生产环境关键配置项是否合理包括Tomcat线程数是否够用、HikariCP连接池是否合理、Actuator端点是否过度暴露、生产环境日志级别是否过高等。30秒跑完5项检查给出具体的修复建议和示例配置。你的Spring Boot项目里这5项配置有几项是默认值的