SpringBoot配置参数
yaml
server:
tomcat:
#线程池配置
max-threads: 200 # 最大工作线程数(建议:2~4倍CPU核心数,如16核设200-400)
min-spare-threads: 20 # 最小空闲线程(应对突发流量,建议:max-threads的10%~20%)
# 连接控制
max-connections: 10000 # 最大连接数(需结合系统句柄数ulimit -n设置,建议:系统句柄数的70% / 应用数)
accept-count: 500 # 等待队列长度(建议:max-threads的1~2倍)
connection-timeout: 5000 # 连接超时(毫秒,建议:3~5秒)
# 高级参数
max-swallow-size: -1 # 处理中断请求的剩余数据(-1表示无限制,大文件上传场景建议设置)
keep-alive:
timeout: 15000 # KeepAlive超时时间(建议:10~15秒)
具体参数项依据和所占比例
在 Spring Boot 中,server.tomcat.max-connections
是 Tomcat 服务器的关键配置参数,用于控制并发连接数上限。它与系统文件句柄数(File Descriptor Limit)直接相关,若配置不当可能导致 Too many open files
错误。以下是详细解释和配置建议:
1. server.tomcat.max-connections
的作用
- 定义:Tomcat 能同时接受的最大连接数(包括活跃和空闲连接)。
- 默认值 :
- Tomcat 8.5+:
10000
(但实际受系统文件句柄数限制)。
- Tomcat 8.5+:
- 场景 :
- 高并发场景(如电商大促、API 网关)需调高此值,避免因连接数不足拒绝请求。
- 低负载场景可适当降低,节省资源。
2. 为什么需要与系统文件句柄数匹配?
(1) 文件句柄(File Descriptor)
- 定义:Linux 系统中,每个 TCP 连接、打开的文件、套接字等都会占用一个文件句柄。
- 默认限制 :
- 系统级全局限制:
cat /proc/sys/fs/file-max
(通常数万到百万)。 - 用户级限制:
ulimit -n
(默认通常为1024
)。
- 系统级全局限制:
(2) 关键关系
- Tomcat 的每个连接需要占用 1~2 个文件句柄(TCP 连接本身和可能的 I/O 缓存)。
- 若
max-connections=10000
,但系统文件句柄数仅为4096
,当并发连接超过 4096 时,会触发java.net.SocketException: Too many open files
错误。
3. 配置建议
(1) 调整系统文件句柄数
-
临时生效(重启失效):
ulimit -n 65535 # 设置当前会话的文件句柄数为 65535
-
永久生效 :
修改
/etc/security/limits.conf
,添加以下内容:* soft nofile 65535 # 所有用户软限制 * hard nofile 65535 # 所有用户硬限制
(2) 合理配置 max-connections
server:
tomcat:
max-connections: 10000 # 建议不超过系统文件句柄数的 70%(如 65535 * 0.7 ≈ 45000)
# 其他参数
max-threads: 200 # 工作线程数(处理请求的核心并发能力)
accept-count: 100 # 等待队列长度(超出后拒绝连接)
(3) 公式参考
max-connections ≤ (系统文件句柄数 - 其他应用占用) * 安全系数
- 示例 :
- 系统文件句柄数为
65535
,假设其他应用占用5000
,安全系数为0.8
。 - 则
max-connections ≤ (65535 - 5000) * 0.8 ≈ 48428
,可配置40000
。
- 系统文件句柄数为
4. 验证与监控
(1) 查看当前文件句柄使用
# 查看系统全局已用句柄数
cat /proc/sys/fs/file-nr
# 查看 Tomcat 进程占用的句柄数
lsof -p <tomcat_pid> | wc -l
(2) 监控 Tomcat 连接数
-
通过 Spring Boot Actuator 的
metrics
端点:bashcurl http://localhost:8080/actuator/metrics/tomcat.connections.max
-
输出示例:
json{ "name": "tomcat.connections.max", "measurements": [{"statistic": "VALUE", "value": 10000}] }
(3) 日志排查
若出现 Too many open files
错误:
- 检查系统文件句柄限制:
ulimit -n
和/proc/sys/fs/file-max
。 - 查看当前连接数:
netstat -an | grep ESTABLISHED | wc -l
。
5. 其他关联参数
参数 | 说明 |
---|---|
server.tomcat.max-threads |
Tomcat 工作线程池大小(决定并发请求处理能力)。 |
server.tomcat.accept-count |
等待队列长度,当所有线程繁忙时,新连接进入队列,超出后拒绝连接。 |
server.connection-timeout |
连接超时时间(毫秒),超时后关闭空闲连接。 |
6. 总结
- 核心原则 :
max-connections
必须小于系统文件句柄数,否则会导致连接拒绝或崩溃。 - 推荐配置 :
- 系统文件句柄数:至少
65535
(通过limits.conf
设置)。 max-connections
:根据业务并发量设定(如10000~40000
)。- 预留 20%~30% 的句柄余量供其他进程(如数据库连接、日志文件)使用。
- 系统文件句柄数:至少
- 高并发场景 :
结合max-threads
和accept-count
,确保线程池和队列能应对突发流量。
合理配置数据库连接数-DRUID配置DRDS
针对 Druid 连接池的性能优化,需从 连接池配置、监控集成、SQL 优化、防御性设计 四个方向入手。以下是详细的优化策略和配置示例:
一、基础配置优化
1. 连接池大小调优
在 application.yml
中配置合理参数(假设 DRDS 最大连接数为 300,3 个应用共存):
yaml
spring:
datasource:
druid:
# 核心连接池参数
initial-size: 5 # 初始连接数(避免冷启动延迟)
min-idle: 5 # 最小空闲连接(维持基本可用性)
max-active: 30 # 最大活跃连接数(按 DRDS 总配额分配)
max-wait: 2000 # 获取连接最大等待时间(毫秒,避免线程阻塞)
# 连接有效性检查
validation-query: SELECT 1 # 心跳检测 SQL(简单查询)
test-on-borrow: true # 借用连接时校验(确保连接有效)
test-while-idle: true # 空闲时定期校验(默认 true)
time-between-eviction-runs-millis: 60000 # 空闲连接检查间隔(60秒)
min-evictable-idle-time-millis: 300000 # 连接最小空闲时间(5分钟)
2. 连接泄漏检测
yaml
spring:
datasource:
druid:
remove-abandoned: true # 启用泄漏连接回收
remove-abandoned-timeout: 300 # 连接被占用超过 300 秒视为泄漏
log-abandoned: true # 记录泄漏连接的堆栈信息(便于排查)
二、启用 Druid 内置监控
1. 开启监控统计功能
yaml
spring:
datasource:
druid:
# 监控统计
stat-view-servlet:
enabled: true # 启用监控页面
url-pattern: /druid/* # 监控访问路径
login-username: admin # 监控账号(生产环境必设)
login-password: druid@123
web-stat-filter:
enabled: true # 启用 Web 请求统计
url-pattern: /* # 统计所有 URL
exclusions: "*.js,*.css,/druid/*" # 排除静态资源
filter:
stat:
enabled: true # 启用 SQL 统计
slow-sql-millis: 1000 # 定义慢 SQL 阈值(1秒)
log-slow-sql: true # 记录慢 SQL 日志
2. 访问监控页面
- 访问
http://your-server:8080/druid
,输入账号密码后可查看:- 实时数据源状态(活跃连接、池大小)。
- SQL 执行统计(执行次数、耗时、慢 SQL)。
- Web 请求监控(URI 访问量、耗时)。
三、防御性设计与性能提升
1. 启用防火墙和 SQL 注入防御
yaml
spring:
datasource:
druid:
filters: stat,wall,slf4j # 启用统计、防火墙、日志过滤器
wall:
enabled: true
config:
delete-allow: false # 禁止 DELETE 无 WHERE 语句
drop-table-allow: false # 禁止 DROP TABLE
multi-statement-allow: false # 禁止批量执行 SQL
2. 预编译语句池(防 SQL 注入 + 性能提升)
yaml
spring:
datasource:
druid:
max-pool-prepared-statement-per-connection-size: 20 # 每个连接缓存的预编译语句数
pool-prepared-statements: true # 启用预编译语句池
3. 异步初始化连接池(加速启动)
yaml
spring:
datasource:
druid:
async-init: true # 异步初始化连接池(避免应用启动阻塞)
四、性能调优参数
1. 连接回收策略优化
yaml
spring:
datasource:
druid:
# 连接存活策略
keep-alive: true # 启用保活机制(默认 false)
phy-timeout-millis: 600000 # 物理连接最大存活时间(10分钟)
# 连接有效性检查优化
validation-query-timeout: 3000 # 心跳检测超时时间(3秒)
五、与 Spring 生态整合
1. 监控数据接入 Actuator
通过 druid-spring-boot-starter
将监控数据暴露给 Spring Boot Actuator:
yaml
management:
endpoints:
web:
exposure:
include: health,druid
2. 分布式链路追踪(如 SkyWalking)
在 druid
过滤器中添加 Trace ID 传递:
java
@Bean
public FilterRegistrationBean<Filter> druidFilter() {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
registration.setFilter(new WebStatFilter());
registration.addInitParameter("exclusions", "*.js,*.css,/druid/*");
registration.addInitParameter("profileEnable", "true");
registration.addUrlPatterns("/*");
return registration;
}
六、维护与监控建议
- 定期分析慢 SQL :
- 通过 Druid 监控页面的
SQL 监控
和慢 SQL 日志
,优化索引和查询逻辑。
- 通过 Druid 监控页面的
- 连接泄漏排查 :
- 启用
remove-abandoned
并分析日志中的泄漏堆栈。
- 启用
- 动态调整参数 :
- 根据业务高峰/低谷期调整
max-active
和max-wait
。
- 根据业务高峰/低谷期调整
- 驱动版本升级 :
- 定期更新 MySQL JDBC 驱动(如
mysql-connector-java:8.0.33
),修复已知性能问题。
- 定期更新 MySQL JDBC 驱动(如
七、完整配置示例
yaml
spring:
datasource:
druid:
url: jdbc:mysql://drds-proxy:3306/db?useSSL=false
username: user
password: pass
initial-size: 5
min-idle: 5
max-active: 30
max-wait: 2000
validation-query: SELECT 1
test-on-borrow: true
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
filters: stat,wall,slf4j
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: admin
login-password: druid@123
web-stat-filter:
enabled: true
url-pattern: /*
wall:
config:
delete-allow: false
async-init: true
keep-alive: true
phy-timeout-millis: 600000
总结
通过上述优化,Druid 连接池可实现:
- 性能提升:合理连接复用、预编译语句缓存、异步初始化。
- 稳定性增强:泄漏检测、慢 SQL 拦截、防火墙规则。
- 可观测性:内置监控 + Spring Actuator 集成,快速定位瓶颈。
- 防御性设计:防止 SQL 注入、限制危险操作。
最终需结合压测工具(如 JMeter)验证配置效果,并根据实际业务负载动态调整参数。
一台服务器上多个程序的JVM参数配置情况
在 16核64G 内存 的服务器上运行 5个 Java 程序(其中两个是核心主应用),需为这两个主应用分配更多资源,同时预留足够内存和 CPU 给其他程序和系统。以下是针对两个主应用的 JVM 参数配置方案及详细说明:
一、配置目标
- 资源隔离:为核心主应用分配更多内存和 CPU,确保高优先级任务稳定运行。
- 稳定性保障:避免内存溢出(OOM)和频繁 Full GC,预留资源给其他 3 个程序。
- 性能优化:根据 16 核特性调整 GC 线程和并行计算能力。
二、主应用 JVM 参数配置
应用 1(核心计算/高吞吐场景)
bash
java -Xms24G -Xmx24G \ # 堆内存 24GB(占 64G 的 37.5%)
-XX:MaxMetaspaceSize=1G \ # 元空间上限 1GB(防类加载泄露)
-XX:MaxDirectMemorySize=4G \ # 堆外内存上限(Netty/NIO 场景需要)
-XX:+UseG1GC \ # 启用 G1 垃圾收集器(平衡吞吐和延迟)
-XX:MaxGCPauseMillis=200 \ # 目标最大 GC 停顿时间 200ms
-XX:ParallelGCThreads=8 \ # 并行 GC 线程数(16核 * 0.5 = 8)
-XX:ConcGCThreads=4 \ # 并发 GC 线程数(ParallelGCThreads * 0.5)
-XX:InitiatingHeapOccupancyPercent=45 \ # 堆占用 45% 触发并发标记
-XX:+ExplicitGCInvokesConcurrent \ # System.gc() 触发并发 GC
-XX:+PrintGCDetails \ # 打印 GC 日志(生产环境可关闭)
-XX:+PrintGCDateStamps \
-Xloggc:/opt/app1_gc.log \
-jar app1.jar
应用 2(低延迟/实时响应场景)
bash
java -Xms20G -Xmx20G \ # 堆内存 20GB(占 64G 的 31.25%)
-XX:MaxMetaspaceSize=1G \
-XX:MaxDirectMemorySize=2G \
-XX:+UseZGC \ # 启用 ZGC(亚毫秒级停顿,JDK 17+)
-XX:ConcGCThreads=8 \ # ZGC 并发线程数(16核 * 0.5 = 8)
-XX:SoftMaxHeapSize=18G \ # 弹性堆内存上限(ZGC 特性)
-XX:+UnlockExperimentalVMOptions \ # 启用实验性参数(JDK 17 需要)
-XX:+ZGenerational \ # 启用分代 ZGC(JDK 21+)
-XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-Xloggc:/opt/app2_gc.log \
-jar app2.jar
三、配置说明
1. 内存分配
资源 | 应用1 | 应用2 | 其他3个程序 | 系统预留 | 总计 |
---|---|---|---|---|---|
堆内存 | 24G | 20G | ~10G | 10G | 64G |
元空间 | 1G | 1G | ~1G | - | 3G |
堆外内存 | 4G | 2G | ~2G | - | 8G |
- 总内存占用 :
24+20+10 +1+1+2 +10= 68G
(略超 64G,需根据实际调整,优先保障主应用)。
2. GC 选择与线程配置
- 应用1(G1 GC) :
ParallelGCThreads=8
:16 核下分配 50% 给并行 GC,避免 GC 线程抢占业务线程。ConcGCThreads=4
:并发标记阶段线程数,减少对业务影响。- 适用场景:高吞吐、允许短暂停顿(如批量处理、数据分析)。
- 应用2(ZGC) :
- 亚毫秒级停顿:适合实时响应场景(如交易系统、API 网关)。
- 分代 ZGC(JDK 21+):减少年轻代回收开销。
SoftMaxHeapSize
:允许堆弹性伸缩,应对突发负载。
3. 防御性参数
MaxMetaspaceSize
:限制元空间,防止第三方库(如反射、动态代理)导致内存泄漏。MaxDirectMemorySize
:控制堆外内存(如 Netty 的 DirectByteBuffer),避免 Native 内存溢出。ExplicitGCInvokesConcurrent
:防止代码调用System.gc()
触发 Full GC。
四、系统级优化
1. CPU 绑定(NUMA 优化)
bash
# 将应用1绑定到 CPU 0-7,应用2绑定到 CPU 8-15(需 root 权限)
taskset -c 0-7 java -Xms24G ... app1.jar
taskset -c 8-15 java -Xms20G ... app2.jar
2. 内存大页(HugePages)
bash
# 配置大页(需系统支持)
-XX:+UseLargePages -XX:LargePageSizeInBytes=2M
3. 文件句柄与网络
bash
# 修改 /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
# 修改 /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535
五、监控与调优
1. 关键监控指标
指标 | 工具 | 健康阈值 |
---|---|---|
JVM Heap Used | VisualVM/Prometheus | < 80% Xmx |
GC Pause Time | GC 日志 | < 200ms(G1)、< 10ms(ZGC) |
CPU Usage | top/htop | < 70%(单核) |
Direct Memory | NMT(Native Memory Tracking) | < MaxDirectMemorySize |
2. 调优步骤
- 基准测试:使用 JMeter 或 Gatling 模拟真实负载,记录 GC 和吞吐量。
- 分析 GC 日志 :检查 Full GC 频率和停顿时间,调整
IHOP
或MaxGCPauseMillis
。 - 堆外内存监控 :通过
jcmd <pid> VM.native_memory
查看 Native 内存分布。 - 动态调整 :根据监控逐步增加
Xmx
或优化代码逻辑(如缓存策略、对象池)。
六、总结
- 应用1(G1):适合高吞吐场景,24G 堆内存 + 并行/并发 GC 线程精细化分配。
- 应用2(ZGC):适合低延迟场景,20G 堆内存 + 分代 ZGC 减少停顿。
- 系统预留:至少 10G 内存给其他 3 个程序及 OS 内核、文件缓存等。
- 监控告警:实时跟踪资源使用,防止主应用挤压其他程序资源。
通过上述配置,可在 16核64G 服务器上实现多应用共存下的资源平衡与性能优化。