最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot監(jiān)控所有線程池的四種解決方案及代碼案例

 更新時(shí)間:2025年12月01日 10:00:03   作者:學(xué)亮編程手記  
這篇文章介紹了四種監(jiān)控Spring Boot中所有線程池的解決方案,并提供了代碼案例,推薦使用自動(dòng)發(fā)現(xiàn)機(jī)制來監(jiān)控所有線程池,需要的朋友可以參考下

問題分析

1.默認(rèn)監(jiān)控的局限性

@Component
public class ThreadPoolMonitor {
    
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor; // 只能監(jiān)控這一個(gè)線程池
    
    public void monitor() {
        // 只能監(jiān)控 taskExecutor 這個(gè)特定的bean
        System.out.println("活躍線程: " + taskExecutor.getActiveCount());
    }
}

解決方案

方案1:手動(dòng)注冊(cè)所有線程池

@Component
public class ThreadPoolMonitor {
    
    private final Map<String, ThreadPoolTaskExecutor> executors = new ConcurrentHashMap<>();
    
    // 手動(dòng)注冊(cè)線程池
    public void registerExecutor(String name, ThreadPoolTaskExecutor executor) {
        executors.put(name, executor);
    }
    
    @Scheduled(fixedRate = 30000)
    public void monitorAll() {
        executors.forEach((name, executor) -> {
            ThreadPoolExecutor pool = executor.getThreadPoolExecutor();
            log.info("線程池[{}] - 活躍: {}/{}, 隊(duì)列: {}/{}, 完成: {}",
                name,
                pool.getActiveCount(),
                pool.getPoolSize(),
                pool.getQueue().size(),
                pool.getQueue().remainingCapacity() + pool.getQueue().size(),
                pool.getCompletedTaskCount());
        });
    }
}

// 在配置中注冊(cè)
@Configuration
public class ExecutorConfig {
    
    @Autowired
    private ThreadPoolMonitor monitor;
    
    @Bean("emailExecutor")
    public ThreadPoolTaskExecutor emailExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 配置...
        executor.initialize();
        
        // 注冊(cè)到監(jiān)控器
        monitor.registerExecutor("emailExecutor", executor);
        return executor;
    }
    
    @Bean("smsExecutor")
    public ThreadPoolTaskExecutor smsExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 配置...
        executor.initialize();
        
        monitor.registerExecutor("smsExecutor", executor);
        return executor;
    }
}

方案2:自動(dòng)發(fā)現(xiàn)所有線程池(推薦)

@Component
public class GlobalThreadPoolMonitor {
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @Scheduled(fixedRate = 30000)
    public void monitorAllThreadPools() {
        // 獲取所有 ThreadPoolTaskExecutor 類型的bean
        Map<String, ThreadPoolTaskExecutor> executors = 
            applicationContext.getBeansOfType(ThreadPoolTaskExecutor.class);
        
        // 獲取所有 ThreadPoolExecutor 類型的bean(直接創(chuàng)建的)
        Map<String, ThreadPoolExecutor> nativeExecutors = 
            applicationContext.getBeansOfType(ThreadPoolExecutor.class);
        
        log.info("=== 線程池監(jiān)控報(bào)告 ===");
        
        // 監(jiān)控 Spring 封裝的線程池
        executors.forEach((beanName, executor) -> {
            if (executor.getThreadPoolExecutor() != null) {
                printPoolStats(beanName, executor.getThreadPoolExecutor());
            }
        });
        
        // 監(jiān)控原生線程池
        nativeExecutors.forEach((beanName, executor) -> {
            printPoolStats(beanName, executor);
        });
    }
    
    private void printPoolStats(String name, ThreadPoolExecutor executor) {
        log.info("線程池[{}]: 活躍{}/核心{}, 隊(duì)列{}/{}, 完成任務(wù): {}, 拒絕: {}",
            name,
            executor.getActiveCount(),
            executor.getPoolSize(),
            executor.getQueue().size(),
            executor.getQueue().size() + executor.getQueue().remainingCapacity(),
            executor.getCompletedTaskCount(),
            executor.getRejectedExecutionHandler().getClass().getSimpleName());
    }
}

方案3:監(jiān)控 @Async 使用的線程池

@Component
public class AsyncThreadPoolMonitor {
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @Scheduled(fixedRate = 30000)
    public void monitorAsyncPools() {
        try {
            // 通過反射獲取Spring內(nèi)部的線程池
            Map<String, Executor> asyncExecutors = 
                applicationContext.getBeansOfType(Executor.class);
            
            asyncExecutors.forEach((name, executor) -> {
                if (executor instanceof ThreadPoolTaskExecutor) {
                    ThreadPoolExecutor pool = ((ThreadPoolTaskExecutor) executor).getThreadPoolExecutor();
                    printAsyncPoolStats(name, pool);
                } else if (executor instanceof ThreadPoolExecutor) {
                    printAsyncPoolStats(name, (ThreadPoolExecutor) executor);
                } else if (executor instanceof TaskExecutor) {
                    log.info("Executor [{}]: 類型 {}", name, executor.getClass().getSimpleName());
                }
            });
        } catch (Exception e) {
            log.warn("監(jiān)控異步線程池失敗: {}", e.getMessage());
        }
    }
    
    private void printAsyncPoolStats(String name, ThreadPoolExecutor pool) {
        double usageRate = pool.getMaximumPoolSize() > 0 ? 
            (double) pool.getActiveCount() / pool.getMaximumPoolSize() * 100 : 0;
            
        log.warn("異步線程池[{}]: 活躍{}/最大{}, 使用率: {:.1f}%, 隊(duì)列: {}/{}",
            name,
            pool.getActiveCount(),
            pool.getMaximumPoolSize(),
            usageRate,
            pool.getQueue().size(),
            pool.getQueue().size() + pool.getQueue().remainingCapacity());
    }
}

方案4:集成Micrometer監(jiān)控(生產(chǎn)環(huán)境推薦)

@Component
public class MicrometerThreadPoolMonitor {
    
    private final MeterRegistry meterRegistry;
    private final List<ThreadPoolExecutor> monitoredPools = new ArrayList<>();
    
    public MicrometerThreadPoolMonitor(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
    
    // 注冊(cè)要監(jiān)控的線程池
    public void registerPool(String name, ThreadPoolExecutor pool) {
        monitoredPools.add(pool);
        
        // 注冊(cè)指標(biāo)
        Gauge.builder("thread.pool.active.count", pool, ThreadPoolExecutor::getActiveCount)
            .tag("pool", name)
            .description("活躍線程數(shù)")
            .register(meterRegistry);
            
        Gauge.builder("thread.pool.queue.size", pool, p -> p.getQueue().size())
            .tag("pool", name)
            .description("隊(duì)列大小")
            .register(meterRegistry);
            
        Gauge.builder("thread.pool.completed.tasks", pool, ThreadPoolExecutor::getCompletedTaskCount)
            .tag("pool", name)
            .description("完成任務(wù)數(shù)")
            .register(meterRegistry);
    }
    
    @EventListener
    public void onApplicationReady(ApplicationReadyEvent event) {
        // 應(yīng)用啟動(dòng)后自動(dòng)發(fā)現(xiàn)并注冊(cè)所有線程池
        ApplicationContext context = event.getApplicationContext();
        
        Map<String, ThreadPoolTaskExecutor> springExecutors = 
            context.getBeansOfType(ThreadPoolTaskExecutor.class);
        
        Map<String, ThreadPoolExecutor> nativeExecutors = 
            context.getBeansOfType(ThreadPoolExecutor.class);
        
        springExecutors.forEach((name, executor) -> {
            if (executor.getThreadPoolExecutor() != null) {
                registerPool("spring-" + name, executor.getThreadPoolExecutor());
            }
        });
        
        nativeExecutors.forEach((name, executor) -> {
            registerPool("native-" + name, executor);
        });
        
        log.info("已注冊(cè)監(jiān)控的線程池?cái)?shù)量: {}", monitoredPools.size());
    }
}

完整的生產(chǎn)級(jí)監(jiān)控方案

@Configuration
public class ThreadPoolMonitorConfig {
    
    @Bean
    @ConditionalOnMissingBean
    public GlobalThreadPoolMonitor globalThreadPoolMonitor() {
        return new GlobalThreadPoolMonitor();
    }
}

@Component
@Slf4j
public class GlobalThreadPoolMonitor {
    
    @Autowired
    private ApplicationContext applicationContext;
    
    private final Map<String, ThreadPoolExecutor> allPools = new ConcurrentHashMap<>();
    
    @PostConstruct
    public void init() {
        discoverAllThreadPools();
    }
    
    @Scheduled(fixedRate = 30000)
    public void monitorAllPools() {
        if (allPools.isEmpty()) {
            discoverAllThreadPools();
        }
        
        log.info("======= 線程池監(jiān)控報(bào)告 =======");
        allPools.forEach(this::logPoolStatus);
        log.info("======= 監(jiān)控報(bào)告結(jié)束 =======");
    }
    
    private void discoverAllThreadPools() {
        // 發(fā)現(xiàn)Spring封裝的線程池
        applicationContext.getBeansOfType(ThreadPoolTaskExecutor.class)
            .forEach((name, executor) -> {
                if (executor.getThreadPoolExecutor() != null) {
                    allPools.put("Spring-" + name, executor.getThreadPoolExecutor());
                }
            });
        
        // 發(fā)現(xiàn)原生線程池
        applicationContext.getBeansOfType(ThreadPoolExecutor.class)
            .forEach((name, executor) -> {
                allPools.put("Native-" + name, executor);
            });
        
        // 發(fā)現(xiàn)所有Executor(包括@Async使用的)
        applicationContext.getBeansOfType(Executor.class)
            .forEach((name, executor) -> {
                if (executor instanceof ThreadPoolTaskExecutor) {
                    ThreadPoolExecutor pool = ((ThreadPoolTaskExecutor) executor).getThreadPoolExecutor();
                    allPools.putIfAbsent("Executor-" + name, pool);
                } else if (executor instanceof ThreadPoolExecutor) {
                    allPools.putIfAbsent("Executor-" + name, (ThreadPoolExecutor) executor);
                }
            });
        
        log.info("發(fā)現(xiàn)線程池?cái)?shù)量: {}", allPools.size());
    }
    
    private void logPoolStatus(String name, ThreadPoolExecutor pool) {
        int activeCount = pool.getActiveCount();
        int poolSize = pool.getPoolSize();
        int queueSize = pool.getQueue().size();
        int queueCapacity = queueSize + pool.getQueue().remainingCapacity();
        long completedTasks = pool.getCompletedTaskCount();
        
        String status = (activeCount == 0) ? "空閑" : "忙碌";
        double usageRate = pool.getMaximumPoolSize() > 0 ? 
            (double) activeCount / pool.getMaximumPoolSize() * 100 : 0;
            
        if (usageRate > 80) {
            log.warn("?? 線程池[{}]: {} 活躍{}/最大{} (使用率{:.1f}%), 隊(duì)列{}/{}", 
                name, status, activeCount, pool.getMaximumPoolSize(), usageRate, 
                queueSize, queueCapacity);
        } else {
            log.info("線程池[{}]: {} 活躍{}/核心{}, 隊(duì)列{}/{}, 完成: {}", 
                name, status, activeCount, poolSize, queueSize, queueCapacity, completedTasks);
        }
    }
    
    // 獲取特定線程池狀態(tài)
    public ThreadPoolStats getPoolStats(String poolName) {
        ThreadPoolExecutor pool = allPools.get(poolName);
        if (pool != null) {
            return new ThreadPoolStats(
                pool.getActiveCount(),
                pool.getPoolSize(),
                pool.getQueue().size(),
                pool.getQueue().remainingCapacity(),
                pool.getCompletedTaskCount()
            );
        }
        return null;
    }
    
    // 統(tǒng)計(jì)類
    @Data
    @AllArgsConstructor
    public static class ThreadPoolStats {
        private int activeCount;
        private int poolSize;
        private int queueSize;
        private int queueRemainingCapacity;
        private long completedTaskCount;
    }
}

總結(jié)

  • 默認(rèn)情況下,ThreadPoolMonitor 只能監(jiān)控直接注入的特定線程池
  • 需要特殊處理才能監(jiān)控所有線程池:
    • 自動(dòng)發(fā)現(xiàn)所有 ThreadPoolTaskExecutorThreadPoolExecutor bean
    • 注冊(cè)機(jī)制手動(dòng)管理
    • 集成監(jiān)控框架如 Micrometer
  • 生產(chǎn)推薦:使用方案2或方案4的自動(dòng)發(fā)現(xiàn)機(jī)制

關(guān)鍵是要在應(yīng)用啟動(dòng)后自動(dòng)發(fā)現(xiàn)所有線程池實(shí)例,而不是依賴單個(gè)注入。

到此這篇關(guān)于SpringBoot監(jiān)控所有線程池的四種解決方案及代碼案例的文章就介紹到這了,更多相關(guān)SpringBoot監(jiān)控所有線程池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

湖南省| 雷山县| 苏尼特右旗| 灵武市| 建湖县| 分宜县| 恩平市| 清水河县| 池州市| 新安县| 哈尔滨市| 信丰县| 纳雍县| 民和| 淳化县| 永德县| 丹江口市| 永吉县| 正镶白旗| 福海县| 西乌| 阿拉尔市| 贵定县| 文成县| 榕江县| 固镇县| 楚雄市| 通河县| 台东市| 广南县| 辽中县| 南阳市| 锦州市| 沂水县| 长海县| 新宁县| 公主岭市| 安丘市| 蓬安县| 丹凤县| 灵川县|