当前位置: 首页 > news >正文

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

接上篇文章, 拿SpringBoot举个例

1.1 默认线程池的隐患
Spring Boot的@Async默认使用SimpleAsyncTaskExecutor(无复用线程),频繁创建/销毁线程易引发性能问题。
1.2 自定义线程池配置
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);          // 核心线程数=CPU核心数×2
        executor.setMaxPoolSize(20);           // 突发流量缓冲
        executor.setQueueCapacity(100);        // 根据业务容忍延迟调整
        executor.setThreadNamePrefix("Async-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

// 使用示例
@Service
public class ReportService {
    @Async  // 指定使用自定义线程池
    public CompletableFuture<Report> generateReportAsync(Long id) {
        // 模拟耗时操作
        Thread.sleep(2000);
        return CompletableFuture.completedFuture(new Report(id, "Done"));
    }
}
1.3 线程池监控(Micrometer + Prometheus)
# application.yml
management:
  endpoints:
    web:
      exposure:
        include: "metrics,prometheus"
  metrics:
    tags:
      application: ${spring.application.name}
@Bean
public MeterBinder threadPoolMetrics(ThreadPoolTaskExecutor executor) {
    return registry -> {
        Gauge.builder("thread.pool.active", executor, ThreadPoolTaskExecutor::getActiveCount)
             .description("当前活跃线程数")
             .register(registry);
        Gauge.builder("thread.pool.queue.size", executor, e -> e.getThreadPoolExecutor().getQueue().size())
             .description("任务队列长度")
             .register(registry);
    };
}

通过http://localhost:8080/actuator/prometheus可获取实时指标。

二、Spring Boot内存泄漏排查:一个真实OOM案例

2.1 故障现象

  • 应用运行24小时后出现java.lang.OutOfMemoryError: Java heap space

  • GC日志显示老年代占用持续增长

2.2 诊断步骤
步骤1:生成堆转储文件

# 在应用启动命令中添加
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof

步骤2:使用MAT分析

  1. 打开heapdump.hprof,选择Dominator Tree

  2. 发现ConcurrentHashMap$Node[]占用80%内存

  3. 查看引用链,定位到缓存工具类未清理过期数据

步骤3:代码修复

// 错误代码:静态Map无限增长
public class CacheManager {
    private static Map<String, Object> cache = new ConcurrentHashMap<>();
    
    public static void put(String key, Object value) {
        cache.put(key, value);
    }
}

// 修复:引入Guava Cache自动过期
public class CacheManager {
    private static LoadingCache<String, Object> cache = CacheBuilder.newBuilder()
        .maximumSize(1000)
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .build(new CacheLoader<>() {
            @Override
            public Object load(String key) {
                return loadFromDB(key);
            }
        });
}
三、Spring Data JPA连接池优化(HikariCP实战)

3.1 默认配置风险
Spring Boot默认使用HikariCP,但以下参数需针对性调整:

spring:
  datasource:
    hikari:
      maximum-pool-size: 20          # 默认10,根据DB并发能力调整
      connection-timeout: 3000       # 获取连接超时时间(ms)
      idle-timeout: 600000           # 空闲连接存活时间(默认10分钟)
      max-lifetime: 1800000          # 连接最大生命周期(默认30分钟)
      leak-detection-threshold: 5000 # 连接泄漏检测阈值(生产环境建议开启)

3.2 监控集成

@Bean
public MeterBinder hikariMetrics(HikariDataSource dataSource) {
    return registry -> {
        HikariPoolMXBean pool = dataSource.getHikariPoolMXBean();
        Gauge.builder("db.pool.active", pool::getActiveConnections)
             .register(registry);
        Gauge.builder("db.pool.idle", pool::getIdleConnections)
             .register(registry);
        Gauge.builder("db.pool.total", pool::getTotalConnections)
             .register(registry);
    };
}
四、生产级Spring Boot JVM参数模板

4.1 基础参数(JDK11+)

java -jar your-app.jar \
  -Xms2g -Xmx2g                 # 堆内存固定,避免动态调整开销 \
  -XX:MaxMetaspaceSize=256m     # 防止元空间膨胀 \
  -XX:+UseG1GC                  # 低延迟垃圾回收器 \
  -XX:MaxGCPauseMillis=200      # 目标最大停顿时间 \
  -Xlog:gc*,gc+heap=debug:file=gc.log:time,uptime:filecount=5,filesize=100m \
  -Dspring.profiles.active=prod

4.2 容器环境适配(Dfile.encoding警告修复)

FROM eclipse-temurin:17-jdk
ENV LANG C.UTF-8
ENV JAVA_OPTS="-Dfile.encoding=UTF-8"
五、实战:利用Arthas在线诊断Spring Boot应用

5.1 安装与附加进程

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar  # 选择目标进程

5.2 常用命令

# 1. 查看实时线程状态
thread -n 3                 # 显示CPU占用最高的3个线程

# 2. 监控方法调用耗时
watch com.example.service.*Service * '{params, returnObj}' -x 3 

# 3. 动态修改日志级别(无需重启)
logger --name ROOT --level debug

 

相关文章:

  • 初探:简道云平台架构及原理
  • 创建HAL版本MDK工程模板
  • 游戏引擎学习第199天
  • 如何访问和使用Sora:OpenAI视频生成模型的完整指南
  • 修改jar包里面的文件方法
  • WEB安全--内网渗透--LMNTLM基础
  • pom导包成功,但是就是无法使用相关类,同时报错:Library:Maven ‘xxx‘ has broken path
  • 【ESP32】ESP32物联网应用:MQTT控制与状态监测
  • SPSS系列1—无聊的列联表卡方检验
  • 【4】数据结构的循环链表章
  • MySQL 存储过程的实用技巧与最佳实践
  • Business English Certificates (BEC) 高频词汇背诵
  • 【C / C++】蓝桥第27场月赛
  • vue2 vue3 响应式差异
  • Android NDK C/C++交叉编译脚本
  • c++使用gstreamer录屏+声音
  • JVM中常见的垃圾回收器(Garbage Collectors)
  • Angular 项目使用 pdf.js 及批注插件Elasticpdf 教程
  • React框架的Concurrent Mode
  • ROS Bag 数据裁剪教程
  • 自己做网站 最好的软件下载/电商运营培训班
  • 武汉做网站seo优化/技能培训网站
  • 做简单最网站的软件是/北京网站制作推广
  • 做二手房的网站技巧/怎样做好网络营销推广
  • 一千元做网站/网站服务器速度对seo有什么影响
  • wordpress 邮件内容/安徽网站关键字优化