
Spring Boot多环境配置性能调优Tomcat与JVMActuator一、环境配置1.Profile机制配置文件命名规则application.yml # 主配置通用所有环境共享 application-{profile}.yml # 环境特定配置加载顺序application.yml→application-{profile}.yml后面覆盖前面若依配置文件结构配置文件作用application.yml主配置应用名、端口、默认激活Profileapplication-druid.yml数据源MySQL连接池配置application-dev.yml开发环境application-test.yml测试环境application-prod.yml生产环境2.Profile激活方式方式一application.yml硬编码开发环境用spring:profiles:active:dev,druid方式二启动命令指定生产推荐java-jarruoyi-admin.jar--spring.profiles.activeprod,druid方式三外部配置文件企业生产标准java-jarruoyi-admin.jar\--spring.config.additional-locationfile:/opt/ruoyi-vue/config/\--spring.profiles.activeprod,druid# 两个启动参数都需要3. 叠加与覆盖规则规则含义Profile叠加多个Profile同时激活不会互相取代配置项覆盖同一配置项出现多次后面的覆盖前面的例--spring.profiles.activeprod,druid→ 同时加载application-prod.yml和application-druid.yml两者的配置都生效。druid为什么能自动激活若依在application.yml中定义了spring.profiles.active: druid作为默认值。正确组合规则一个环境Profile 多个功能Profile✅prod,druid正确❌test,prod两个环境Profile冲突4.若依生产环境配置目录结构/opt/ruoyi-vue/ ├── app/ │ └── ruoyi-admin.jar # 同一个JAR包 ├── config/ │ ├── application.yml # 主配置激活哪些Profile │ ├── application-prod.yml # 生产环境配置 │ ├── application-druid.yml # 数据源配置含密码不打包进JAR │ └── application-log.yml # 日志配置可选 └── logs/ └── ruoyi.log启动命令java-jar/opt/ruoyi-vue/app/ruoyi-admin.jar\--spring.config.additional-locationfile:/opt/ruoyi-vue/config/\--spring.profiles.activeprod,druid典型配置文件# 主配置文件sudovim/opt/ruoyi-vue/config/application.yml spring: profiles: active: prod,druid# 环境配置文件sudovim/opt/ruoyi-vue/config/application-prod.yml spring: datasource: druid: master: url: jdbc:mysql://prod-mysql:3306/ruoyi?... username: ruoyi_prod password:123456data: redis: host: prod-redis port:6379password:123456logging: level: com.ruoyi: warn file: name: /opt/ruoyi-vue/logs/ruoyi.log server: port:8080# 连接池参数配置文件sudovim/opt/ruoyi-vue/config/application-druid.yml spring: datasource: druid: initial-size:5min-idle:10max-active:30max-wait:60000time-between-eviction-runs-millis:60000stat-view-servlet: enabled:trueurl-pattern: /druid/*Druid连接池关键参数**参数推荐值含义initial-size5启动时预创建连接min-idle10最少保持空闲连接max-active30最大活跃连接max-wait60000ms获取连接最长等待时间time-between-eviction-60000ms每隔 60 秒检查一次闲置stat-view-servlet.enabledtrue开启 Druid 监控页面(/druid/* 二、性能调优Tomcat与JVM1.调优的两个核心对象无论JAR还是WAR包调优对象都是Tomcat JVM。差异仅在于配置位置参数类型JAR包若依Vue版WAR包传统项目Tomcat参数application.ymlconf/server.xmlJVM参数Systemd服务文件bin/setenv.sh2.Tomcat调优——四个维度2.1线程池调优# application.ymlserver:tomcat:threads:max:200# 最大工作线程数4核:200-300, 8核:400-600min-spare:20# 最小空闲线程数accept-count:200# 等待队列长度maxThreads的50%-100%connection-timeout:20000# 连接超时msmax-connections:10000# 最大连接数compression:on# 启动压缩compression-min-size:2048# 大于等于2048k才进行压缩protocol:org.apache.coyote.http11.Http11Nio2Protocol# I/O模型配置2.2连接器调优参数含义生产建议connectionTimeout连接超时10000-30000msacceptCount等待队列maxThreads的50%-100%不是越大越好compression启用压缩on减少传输量2.3I/O模型选择模型适用场景性能BIO低并发200连接差NIO高并发Web应用好NIO2高并发异步IO更好推荐APR极致性能最好生产环境推荐NIO21000并发下比BIO响应时间缩短约67%。3. JVM调优核心内存参数参数含义生产建议-Xms初始堆内存与-Xmx设相同值-Xmx最大堆内存物理内存的50%-70%-XX:MetaspaceSize元空间初始大小256m-XX:MaxMetaspaceSize元空间最大大小512m-XX:UseG1GC使用G1回收器低延迟场景推荐-XX:MaxGCPauseMillis200GC最大暂停时间200ms-XX:HeapDumpOnOutOfMemoryErrorOOM时导出堆转储必须开启不同内存服务器参考服务器内存-Xms/-Xmx适用场景4GB1g开发/测试8GB4g生产若依推荐16GB8g高并发生产Systemd服务文件完整JVM配置ExecStart/usr/bin/java \ -Xms4g -Xmx4g \ -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m \ -XX:UseG1GC -XX:MaxGCPauseMillis200 \ -XX:G1HeapRegionSize16m \ -XX:InitiatingHeapOccupancyPercent45 \ -XX:HeapDumpOnOutOfMemoryError \ -XX:HeapDumpPath/opt/ruoyi-vue/logs/heapdump.hprof \ -jar /opt/ruoyi-vue/app/ruoyi-admin.jar4 GC回收器选择回收器适用场景状态Serial单核/小内存1GB不推荐Parallel Scavenge多核/吞吐量优先JDK 8默认CMS停顿敏感200msJDK 14已移除G1大堆6GB/可预测停顿当前主流推荐ZGC超大堆TB级/极低延迟10msJDK 15未来趋势结论JDK 8/11/17统一推荐G1。JDK 17且延迟要求50ms可考虑ZGC。5.JVM诊断命令# 1. 查看Java进程jps-l# 2. 实时查看GC情况每秒刷新jstat-gcutilPID1s# 重点关注O老年代使用率应70%、FGCFull GC次数应极少# 3. 查看最占内存的对象jmap-histoPID|head-n20# 4. 查看堆内存配置JDK 11jhsdb jmap--heap--pidPID# 注意jhsdb 需要安装 java-17-openjdk-devel 包6. 排障速查表症状可能原因调优方向请求超时/响应慢maxThreads太小增大maxThreads、acceptCount频繁Full GC堆内存不足或GC策略不当增大-Xmx改用G1GC大量TIME_WAIT连接未复用调整keepAliveTimeoutToo many open files文件描述符不够ulimit -n 65535OOM堆太小或内存泄漏增大-Xmx分析heap dump7.Tomcat线程池 vs 数据库连接池对比维度Tomcat线程池HikariCP连接池管理对象Java工作线程MySQL数据库连接解决的问题同时处理多少用户请求同时连接数据库多少次若依默认值20010生产建议200-50020-50两者需要匹配Tomcat 200线程但连接池只有10个最多10个请求能同时查数据库其他190个都在等。三、 Actuator监控与动态日志1.Actuator是什么Spring Boot自带的监控工具提供HTTP端点查看应用运行状态无需登录服务器执行JVM命令。2.配置步骤Step 1添加依赖# 在 ruoyi-admin 模块的 pom.xml文件下dependencies模块中添加 !-- ruoyi-admin/pom.xml -- !-- Spring Boot Actuator 监控依赖 -- !-- 提供生产级别的应用监控和管理功能包括健康检查、指标收集、环境信息等端点 -- !-- 版本由 spring-boot-starter-parent 统一管理无需显式指定 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId !--有可能需要增加版本 version2.7.18/version -- /dependencyStep 2配置application.yml# 建议放在主配置文件中 application.ymlsudo vim /opt/ruoyi-vue/config/application-prod.ymlmanagement:endpoints:web:base-path:/actuator# 访问路径前缀默认可不显示指定exposure:include:*# 暴露所有端点不安全 生产环境推荐health,info,metricsendpoint:health:show-details:always# 健康检查显示详细信息always生产推荐# include: *表示已开启以下端点监控metrics:enabled:true# 启用 metrics监控端点生产环境默认关闭heapdump:enabled:true# 启用 heapdump监控端点生产环境默认关闭Step 3放行Spring Security鉴权sudovimRuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java // 除上面外的所有请求全部需要鉴权认证 .requestMatchers(/actuator/**).permitAll()# 添加该行.anyRequest().authenticated();Step 4重新打包、部署、验证# 1. 重新打包cd/home/wangchen/RuoYi-Vue mvn clean package-DskipTests# 2. 部署新JAR包sudocpruoyi-admin/target/ruoyi-admin.jar /opt/ruoyi-vue/app/# 3. 重启服务sudosystemctl restart ruoyi-vue# 4. 验证Actuator是否生效curlhttp://localhost:8080/actuator/health# 返回 {status:UP} 即配置成功curlhttp://localhost:8080/actuator/health# 返回 {status:UP} 即配置成功3.核心端点/health — 健康检查curlhttp://localhost:8080/actuator/health|jq返回各组件状态MySQL、Redis、diskSpace某组件DOWN则检查对应服务。|jq表示管道给jq,以jq格式显示/metrics — 性能指标# 查看所有可用指标curlhttp://localhost:8080/actuator/metrics|jq# 查看具体的某个指标curl-shttp://localhost:8080/actuator/metrics/jvm.gc.pause|jq# 查看以jvm.gc开头的指标curl-shttp://localhost:8080/actuator/metrics|jq.names[] | select(contains(jvm.gc))# GC 相关指标:jvm.gc.live.data.size - 存活数据大小 jvm.gc.max.data.size - 最大数据大小 jvm.gc.memory.allocated - 分配的内存 jvm.gc.memory.promoted - 提升的内存 jvm.gc.overhead - GC 开销 jvm.gc.pause - GC 暂停时间# 查看GC暂停时间curlhttp://localhost:8080/actuator/metrics/jvm.gc.pause|jq# 老年代使用量G1垃圾回收器curl-shttp://localhost:8080/actuator/metrics/jvm.memory.used?tagarea:heaptagid:G1%20Old%20Gen|jq.measurements[0].value / 1024 / 1024 / 10240.0325474739074707# 查看堆内存使用量MBcurlhttp://localhost:8080/actuator/metrics/jvm.memory.used?tagarea:heap|jq# 查看当前激活的Profilecurlhttp://localhost:8080/actuator/env|jq.activeProfiles/heapdump——堆内存快照curl-o/tmp/heap.hprof http://localhost:8080/actuator/heapdump % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed10081.3M10081.3M00174M0--:--:-- --:--:-- --:--:-- 174M/loggers — 动态日志不重启调日志级别# 查看当前级别curlhttp://localhost:8080/actuator/loggers/com.ruoyi# 临时调整为DEBUGcurl-XPOST http://localhost:8080/actuator/loggers/com.ruoyi\-HContent-Type: application/json\-d{configuredLevel: DEBUG}# 恢复为INFO用完即关curl-XPOST http://localhost:8080/actuator/loggers/com.ruoyi\-HContent-Type: application/json\-d{configuredLevel: null}排障工作流开启DEBUG → 复现问题 → 收集日志 → 恢复INFO → 分析日志。4.生产环境安全配置端点是否暴露原因/health暴露Nginx/K8s健康检查需要/info暴露查看版本信息/metrics内网或认证包含敏感性能指标/loggers内网或认证可动态改日志级别/heapdump不暴露可下载完整堆内存非常敏感/env不暴露暴露数据库密码等敏感配置/shutdown绝对不暴露可远程关闭应用生产推荐配置management:endpoints:web:exposure:include:health,info,metrics# 只暴露三个endpoint:health:show-details:alwaysserver:port:9099# 独立管理端口address:127.0.0.1# 只允许本机访问5. Prometheus集成management:endpoints:web:exposure:include:health,info,prometheus# Prometheus采集端点curlhttp://localhost:9099/actuator/prometheus运维高频命令速查# Java进程管理 jps-l# 查看Java进程jstat-gcutilPID1s# 实时GC监控jmap-histoPID|head-n20# 最占内存的对象jhsdb jmap--heap--pidPID# 堆内存配置JDK 11# Maven构建 mvn clean package-DskipTests# 生产最常用构建命令mvn clean deploy-DskipTests# 构建并上传Nexus# Actuator监控 curllocalhost:8080/actuator/health# 健康检查curllocalhost:8080/actuator/metrics# 性能指标列表curllocalhost:8080/actuator/loggers/com.ruoyi# 查看日志级别