性能优化-Spring参数配置、数据库连接参数配置、JVM调优

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(但实际受系统文件句柄数限制)。
  • 场景
    • 高并发场景(如电商大促、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 端点:

    bash 复制代码
    curl 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-threadsaccept-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;
}

六、维护与监控建议

  1. 定期分析慢 SQL
    • 通过 Druid 监控页面的 SQL 监控慢 SQL 日志,优化索引和查询逻辑。
  2. 连接泄漏排查
    • 启用 remove-abandoned 并分析日志中的泄漏堆栈。
  3. 动态调整参数
    • 根据业务高峰/低谷期调整 max-activemax-wait
  4. 驱动版本升级
    • 定期更新 MySQL JDBC 驱动(如 mysql-connector-java:8.0.33),修复已知性能问题。

七、完整配置示例

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 连接池可实现:

  1. 性能提升:合理连接复用、预编译语句缓存、异步初始化。
  2. 稳定性增强:泄漏检测、慢 SQL 拦截、防火墙规则。
  3. 可观测性:内置监控 + Spring Actuator 集成,快速定位瓶颈。
  4. 防御性设计:防止 SQL 注入、限制危险操作。

最终需结合压测工具(如 JMeter)验证配置效果,并根据实际业务负载动态调整参数。

一台服务器上多个程序的JVM参数配置情况

16核64G 内存 的服务器上运行 5个 Java 程序(其中两个是核心主应用),需为这两个主应用分配更多资源,同时预留足够内存和 CPU 给其他程序和系统。以下是针对两个主应用的 JVM 参数配置方案及详细说明:


一、配置目标

  1. 资源隔离:为核心主应用分配更多内存和 CPU,确保高优先级任务稳定运行。
  2. 稳定性保障:避免内存溢出(OOM)和频繁 Full GC,预留资源给其他 3 个程序。
  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. 调优步骤
  1. 基准测试:使用 JMeter 或 Gatling 模拟真实负载,记录 GC 和吞吐量。
  2. 分析 GC 日志 :检查 Full GC 频率和停顿时间,调整 IHOPMaxGCPauseMillis
  3. 堆外内存监控 :通过 jcmd <pid> VM.native_memory 查看 Native 内存分布。
  4. 动态调整 :根据监控逐步增加 Xmx 或优化代码逻辑(如缓存策略、对象池)。

六、总结

  • 应用1(G1):适合高吞吐场景,24G 堆内存 + 并行/并发 GC 线程精细化分配。
  • 应用2(ZGC):适合低延迟场景,20G 堆内存 + 分代 ZGC 减少停顿。
  • 系统预留:至少 10G 内存给其他 3 个程序及 OS 内核、文件缓存等。
  • 监控告警:实时跟踪资源使用,防止主应用挤压其他程序资源。

通过上述配置,可在 16核64G 服务器上实现多应用共存下的资源平衡与性能优化。

相关推荐
Chandler242 小时前
一图掌握 MySQL 核心要点
数据库·mysql
CodeJourney.2 小时前
从PPT到DeepSeek开启信息可视化的全新之旅
数据库·人工智能·算法·excel·流程图
体育分享_大眼3 小时前
从零搭建高并发体育直播网站:架构设计、核心技术与性能优化实战
java·性能优化·系统架构
GOTXX7 小时前
【Qt】Qt Creator开发基础:项目创建、界面解析与核心概念入门
开发语言·数据库·c++·qt·图形渲染·图形化界面·qt新手入门
猿小喵7 小时前
记录一次TDSQL网关夯住故障
运维·数据库·mysql
电商api接口开发7 小时前
如何在C#中使用LINQ对数据库进行查询操作?
数据库·c#·linq
hnsqls8 小时前
Redis 常问知识
数据库·redis·缓存
小丁爱养花9 小时前
驾驭 Linux 云: JavaWeb 项目安全部署
java·linux·运维·服务器·spring boot·后端·spring
一个小白19 小时前
C++ 用红黑树封装map/set
java·数据库·c++