前言
Spring Boot配置优化,每个配置都附有代码和详解,即使刚接触也能轻松上手(注:具体配置需结合实际使用的Spring Boot版本进行调整)。
一、Tomcat连接池配置:应对高并发的"交通指挥官"
Spring Boot默认集成Tomcat服务器,但默认连接池参数偏保守,高并发时容易出现"请求排队、响应变慢"的问题,就像"窄马路容不下太多车"。我们需要调整参数,让Tomcat能"容纳更多请求、快速处理任务"。
配置方案
yaml
server:
tomcat:
max-connections: 10000 # 最大连接数 默认:8192
threads:
max: 800 # 最大工作线程数 默认:200
min-spare: 100 # 最小空闲线程数 默认:10
accept-count: 100 # 等待队列长度 默认:100
connection-timeout: 20000 # 连接超时时间(毫秒),默认未配置
参数解释
max-connections
:Tomcat能同时处理的最大连接数,默认8192,高并发场景可调至10000;threads.max
:处理请求的"最大工作人员数量",线程越多,同时处理的请求越多,默认200,根据服务器CPU核数调整(一般设为CPU核数的2-4倍);threads.min-spare
:即使没请求,也保留的"空闲工作人员数量",避免请求突然增多时"没人干活";connection-timeout
:请求等待超时时间,超过这个时间就拒绝请求,防止"无效请求占用资源"。
二、数据库连接池配置:给数据库"配好接待员"
Spring Boot默认用HikariCP作为数据库连接池(性能最优的连接池之一),但默认最大连接数仅10,若项目并发高,会出现"数据库连接不够用,请求卡壳"的情况,就像"餐厅只有10个服务员,客人多了要排队"。
配置方案
yaml
spring:
datasource:
hikari:
maximum-pool-size: 50 # 最大连接数,默认:10
minimum-idle: 10 # 最小空闲连接,默认:10
connection-timeout: 30000 # 连接超时时间(毫秒)
idle-timeout: 600000 # 空闲连接超时时间,默认:600000(10分钟)
max-lifetime: 1800000 # 连接最大存活时间,默认:1800000(30分钟)
leak-detection-threshold: 60000 # 连接泄露检查阈值,默认:0(关闭)
参数解释
maximum-pool-size
:连接池里的"最大服务员数量",根据数据库性能调整(比如MySQL建议设为20-50),太多会给数据库造成压力;minimum-idle
:连接池里"常驻的空闲服务员",保证随时有连接可用,不用每次都"临时招人";idle-timeout
:空闲连接"多久没活干就释放掉",避免"占着位置不干活";leak-detection-threshold
:开启"连接泄露检查",若连接超过60秒没归还,就报警提示,防止代码bug导致连接浪费。
三、Jackson时区序列化:解决分布式"时间混乱"
Spring Boot默认用Jackson处理JSON序列化,但会用系统时区------如果项目部署在不同时区的服务器(比如一台在上海、一台在北京),会出现"同一时间显示不同"的问题,就像"有的表走北京时间,有的走格林尼治时间"。
配置方案
yaml
spring:
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
serialization:
write-dates-as-timestamps: false
参数解释
time-zone: GMT+8
:强制用东八区(北京时间),不管服务器在哪个时区,时间显示都统一;date-format
:指定时间格式为"年-月-日 时:分:秒",避免返回"时间戳"(数字),前端更易处理;write-dates-as-timestamps: false
:关闭"时间戳模式",用上面指定的格式返回时间。
四、日志配置:给日志"装个管家"
Spring Boot默认用Logback日志框架,但默认配置不会"滚动清理日志"------日志文件会一直变大,最终占满硬盘,就像"垃圾不分类不清理,堆满房间"。我们需要让日志"按大小滚动、定时清理"。
配置方案
yaml
logging:
file:
name: app.log # 日志文件名
logback:
rollingpolicy:
max-file-size: 100MB # 单个日志文件最大大小
max-history: 30 # 日志保留30天
total-size-cap: 3GB # 所有日志文件总大小上限
参数解释
max-file-size
:单个日志文件最大100MB,满了就自动生成新文件(比如app.log→app.1.log→app.2.log);max-history
:30天前的日志自动删除,不用手动清理;total-size-cap
:所有日志文件加起来不超过3GB,避免占满硬盘。
五、缓存配置:替代默认缓存,避免"内存爆炸"
Spring Boot的@Cacheable
注解默认用ConcurrentHashMap实现缓存,但这个实现是"没有管理员"的,导致缓存会无限堆积,高并发时会导致内存溢出,就像"仓库无限囤货,最终塌了"。推荐用Caffeine替代,它能"限大小、定时清理"。
配置方案
yaml
spring:
cache:
type: caffeine # 指定缓存类型为Caffeine
caffeine:
spec: maximumSize=10000,expireAfterWrite=600s # 缓存规则
参数解释
type: caffeine
:告诉Spring Boot不用默认缓存,改用Caffeine;maximumSize=10000
:缓存最多存10000条数据,满了就淘汰"最久不用的";expireAfterWrite=600s
:数据存入缓存后,600秒(10分钟)后自动过期,避免数据过时。
六、监控端点配置:暴露必要信息,避免"隐私泄露"
Spring Boot Actuator默认暴露很多监控端点(比如健康检查、配置信息、环境变量),若全部开放,可能泄露敏感信息(比如数据库密码),就像"家门不锁,陌生人能进客厅"。我们只需暴露必要端点,并控制访问权限。
配置方案
yaml
management:
endpoints:
web:
exposure:
include: health,info,metrics # 只暴露3个必要端点
endpoint:
health:
show-details: when-authorized # 健康详情只给授权用户看
参数解释
include: health,info,metrics
:只开放3个安全端点:health
(服务健康状态)、info
(项目基本信息)、metrics
(服务指标,如CPU使用率);show-details: when-authorized
:健康检查的详细信息(比如数据库是否连接成功),只给授权用户看,避免陌生人获取。
七、文件上传大小限制:突破"1MB瓶颈"
Spring Boot默认的文件上传限制极严格:单个文件只能传1MB,整个请求最大10MB------传张高清图片、一个压缩包都会失败,就像"水管太细,大水流不过来"。我们需要扩大限制。
配置方案
yaml
spring:
servlet:
multipart:
max-file-size: 100MB # 单个文件最大大小
max-request-size: 100MB # 整个请求最大大小
file-size-threshold: 2KB # 超过2KB的文件先存硬盘(不占内存)
location: /tmp # 临时文件存储路径
resolve-lazily: false # 不延迟解析请求(默认false)
参数解释
max-file-size
:单个文件最大100MB,满足大部分场景(如传高清图、Excel表格);max-request-size
:整个请求(比如一次传多个文件)最大100MB,避免请求过大;file-size-threshold
:小于2KB的文件存在内存(快),大于的存硬盘(省内存)。
八、异步线程池配置:避免"线程泛滥"
用@Async
注解实现异步任务时,Spring Boot默认用SimpleAsyncTaskExecutor------这个执行器"每次都新创建线程",高并发时会生成大量线程,导致"系统资源耗尽",就像"每次办事都找新临时工,人太多管理不过来"。我们需要配置线程池,实现"线程复用"。
配置方案
yaml
spring:
task:
execution:
pool:
core-size: 8 # 核心线程数(常驻线程)
max-size: 16 # 最大线程数
queue-capacity: 100 # 任务队列容量
keep-alive: 60s # 空闲线程存活时间
thread-name-prefix: async-task- # 线程名前缀(方便排查问题)
scheduling:
pool:
size: 4 # 定时任务线程池大小
thread-name-prefix: scheduling- # 定时任务线程名前缀
参数解释
core-size
:线程池里"常驻的工作人员",即使没任务也不销毁,保证快速响应;max-size
:线程池里"最多能有多少工作人员",任务太多时临时加人,任务少了再减到核心数;queue-capacity
:任务太多时,先放进"等待队列",避免直接创建新线程;thread-name-prefix
:给线程起个统一前缀(如async-task-1
),排查日志时能快速识别异步线程。
九、静态资源缓存策略:让页面加载"飞起来"
Spring Boot默认不给静态资源(CSS、JS、图片)设置HTTP缓存头------浏览器每次访问都要重新下载这些文件,页面加载慢,就像"每次看同一本书都要重新买一本"。我们需要配置缓存,让浏览器"重复利用已下载的资源"。
配置方案
yaml
spring:
web:
resources:
cache:
cachecontrol:
max-age: 365d # 静态资源缓存365天
cache-public: true # 允许公共缓存(如CDN)
chain:
strategy:
content:
enabled: true # 开启内容版本化
paths: /** # 所有静态资源都生效
cache: true # 开启资源链缓存
static-locations: classpath:/static/ # 静态资源存放路径
参数解释
max-age: 365d
:浏览器下载静态资源后,365天内不用重新请求,直接用本地缓存;content: enabled: true
:开启"内容版本化"------Spring Boot会根据文件内容生成MD5哈希值(如style-abc123.css
),文件变了哈希值也变,浏览器会自动下载新文件;文件没变则用缓存,兼顾"快"和"新"。
十、数据库事务超时配置:避免"长事务锁表"
用@Transactional
注解时,Spring Boot默认不设置事务超时时间------如果事务里处理大量数据(比如批量导入10万条数据),会"长时间持有数据库锁",导致其他操作卡住,就像"占着厕所不出来,别人没法用"。我们需要给事务设超时,并分批处理数据。
配置方案
java
@Transactional(timeout = 30, rollbackFor = Exception.class)
public void batchProcess(List<Data> dataList) {
// 分批处理,避免长事务
int batchSize = 100;
for (int i = 0; i < dataList.size(); i += batchSize) {
List<Data> batch = dataList.subList(i,
Math.min(i + batchSize, dataList.size()));
processBatch(batch);
}
}
参数通俗解释
timeout = 30
:事务超时时间设为30秒,若30秒内没完成,自动回滚,释放数据库锁;rollbackFor = Exception.class
:遇到任何异常都回滚事务,避免数据不一致;- 分批处理:把10万条数据分成每100条一批,每批处理完就提交事务,缩短单次事务时长,减少锁表时间。
总结:配置的核心是"适配需求"
Spring Boot的配置没有"万能模板",本文的参数是基于常见场景的优化建议------实际项目中,你需要结合自己的Spring Boot版本、服务器性能、业务并发量进行调整(比如小项目不用把Tomcat最大连接数设到10000)。