接上文,SpringBoot的线程池设置以及JVM监控

打印 上一主题 下一主题

主题 1852|帖子 1852|积分 5556

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
接上篇文章, 拿SpringBoot举个例
1.1 默认线程池的隐患
Spring Boot的@Async默认利用SimpleAsyncTaskExecutor(无复用线程),频繁创建/销毁线程易引发性能标题。


1.2 自定义线程池设置

  1. @Configuration
  2. @EnableAsync
  3. public class AsyncConfig implements AsyncConfigurer {
  4.     @Override
  5.     public Executor getAsyncExecutor() {
  6.         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  7.         executor.setCorePoolSize(10);          // 核心线程数=CPU核心数×2
  8.         executor.setMaxPoolSize(20);           // 突发流量缓冲
  9.         executor.setQueueCapacity(100);        // 根据业务容忍延迟调整
  10.         executor.setThreadNamePrefix("Async-");
  11.         executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  12.         executor.initialize();
  13.         return executor;
  14.     }
  15. }
  16. // 使用示例
  17. @Service
  18. public class ReportService {
  19.     @Async  // 指定使用自定义线程池
  20.     public CompletableFuture<Report> generateReportAsync(Long id) {
  21.         // 模拟耗时操作
  22.         Thread.sleep(2000);
  23.         return CompletableFuture.completedFuture(new Report(id, "Done"));
  24.     }
  25. }
复制代码
1.3 线程池监控(Micrometer + Prometheus)

  1. # application.yml
  2. management:
  3.   endpoints:
  4.     web:
  5.       exposure:
  6.         include: "metrics,prometheus"
  7.   metrics:
  8.     tags:
  9.       application: ${spring.application.name}
复制代码
  1. @Bean
  2. public MeterBinder threadPoolMetrics(ThreadPoolTaskExecutor executor) {
  3.     return registry -> {
  4.         Gauge.builder("thread.pool.active", executor, ThreadPoolTaskExecutor::getActiveCount)
  5.              .description("当前活跃线程数")
  6.              .register(registry);
  7.         Gauge.builder("thread.pool.queue.size", executor, e -> e.getThreadPoolExecutor().getQueue().size())
  8.              .description("任务队列长度")
  9.              .register(registry);
  10.     };
  11. }
复制代码
通过http://localhost:8080/actuator/prometheus可获取实时指标。
二、Spring Boot内存泄漏排查:一个真实OOM案例

2.1 故障征象


  • 应用运行24小时后出现java.lang.OutOfMemoryError: Java heap space
  • GC日志表现老年代占用连续增长
2.2 诊断步骤
步骤1:天生堆转储文件
  1. # 在应用启动命令中添加
  2. -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof
复制代码
步骤2:利用MAT分析

  • 打开heapdump.hprof,选择Dominator Tree
  • 发现ConcurrentHashMap$Node[]占用80%内存
  • 查察引用链,定位到缓存工具类未清算逾期数据
步骤3:代码修复
  1. // 错误代码:静态Map无限增长
  2. public class CacheManager {
  3.     private static Map<String, Object> cache = new ConcurrentHashMap<>();
  4.    
  5.     public static void put(String key, Object value) {
  6.         cache.put(key, value);
  7.     }
  8. }
  9. // 修复:引入Guava Cache自动过期
  10. public class CacheManager {
  11.     private static LoadingCache<String, Object> cache = CacheBuilder.newBuilder()
  12.         .maximumSize(1000)
  13.         .expireAfterWrite(10, TimeUnit.MINUTES)
  14.         .build(new CacheLoader<>() {
  15.             @Override
  16.             public Object load(String key) {
  17.                 return loadFromDB(key);
  18.             }
  19.         });
  20. }
复制代码
三、Spring Data JPA连接池优化(HikariCP实战)

3.1 默认设置风险
Spring Boot默认利用HikariCP,但以下参数需针对性调解:
  1. spring:
  2.   datasource:
  3.     hikari:
  4.       maximum-pool-size: 20          # 默认10,根据DB并发能力调整
  5.       connection-timeout: 3000       # 获取连接超时时间(ms)
  6.       idle-timeout: 600000           # 空闲连接存活时间(默认10分钟)
  7.       max-lifetime: 1800000          # 连接最大生命周期(默认30分钟)
  8.       leak-detection-threshold: 5000 # 连接泄漏检测阈值(生产环境建议开启)
复制代码
3.2 监控集成
  1. @Bean
  2. public MeterBinder hikariMetrics(HikariDataSource dataSource) {
  3.     return registry -> {
  4.         HikariPoolMXBean pool = dataSource.getHikariPoolMXBean();
  5.         Gauge.builder("db.pool.active", pool::getActiveConnections)
  6.              .register(registry);
  7.         Gauge.builder("db.pool.idle", pool::getIdleConnections)
  8.              .register(registry);
  9.         Gauge.builder("db.pool.total", pool::getTotalConnections)
  10.              .register(registry);
  11.     };
  12. }
复制代码
四、生产级Spring Boot JVM参数模板

4.1 基础参数(JDK11+)
  1. java -jar your-app.jar \
  2.   -Xms2g -Xmx2g                 # 堆内存固定,避免动态调整开销 \
  3.   -XX:MaxMetaspaceSize=256m     # 防止元空间膨胀 \
  4.   -XX:+UseG1GC                  # 低延迟垃圾回收器 \
  5.   -XX:MaxGCPauseMillis=200      # 目标最大停顿时间 \
  6.   -Xlog:gc*,gc+heap=debug:file=gc.log:time,uptime:filecount=5,filesize=100m \
  7.   -Dspring.profiles.active=prod
复制代码
4.2 容器环境适配(Dfile.encoding警告修复)
  1. FROM eclipse-temurin:17-jdk
  2. ENV LANG C.UTF-8
  3. ENV JAVA_OPTS="-Dfile.encoding=UTF-8"
复制代码
五、实战:利用Arthas在线诊断Spring Boot应用

5.1 安装与附加进程
  1. curl -O https://arthas.aliyun.com/arthas-boot.jar
  2. java -jar arthas-boot.jar  # 选择目标进程
复制代码
5.2 常用命令
  1. # 1. 查看实时线程状态
  2. thread -n 3                 # 显示CPU占用最高的3个线程
  3. # 2. 监控方法调用耗时
  4. watch com.example.service.*Service * '{params, returnObj}' -x 3
  5. # 3. 动态修改日志级别(无需重启)
  6. logger --name ROOT --level debug
复制代码
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

河曲智叟

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表