Operations 8 min read

Using Prometheus for Custom Thread‑Pool Monitoring and Alerting in a Spring Boot Backend

This article explains how Prometheus can be used to monitor custom thread‑pool metrics in a Spring Boot backend, detailing configuration, dynamic parameter updates via Apollo, code examples for metric registration, and visualization and alerting with Grafana.

政采云技术
政采云技术
政采云技术
Using Prometheus for Custom Thread‑Pool Monitoring and Alerting in a Spring Boot Backend

What is Prometheus

Prometheus, named after the Greek god of foresight, is a monitoring and alerting solution that turns metrics into insights. It provides a complete data‑monitoring platform that can be quickly visualized with Grafana.

Business Practice

Background

A business requires n experts to sign n reports, but the signing API only supports one‑report signing, leading to an n×n signing process that is complex and long‑running. The signing step is a critical node, so monitoring the thread‑pool metrics that drive this process is essential.

Implementation

Custom thread‑pool metrics are exposed to Prometheus, visualized in Grafana, and the thread‑pool parameters are dynamically adjusted through Apollo for elastic scaling.

Dynamic Thread‑Pool Parameter Update

When Apollo detects a change in thread‑pool configuration, the following parameters are updated:

Core thread count

Maximum thread count

Thread idle timeout

@Component
public class ApolloRefreshConfig {
    @Resource
    private RefreshScope refreshScope;
    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private ThreadPoolExecutor executorService;

    @ApolloConfigChangeListener
    public void onChange(ConfigChangeEvent changeEvent) {
        applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
        refreshScope.refreshAll();
        // Refresh variables
        asyncRequestTaskConfigChange(changeEvent.changedKeys());
    }

    private void asyncRequestTaskConfigChange(Set
changedKeys) {
        // Apollo changes thread‑pool variables
        if (changedKeys.contains(EvaluationProcessAsyncRequestTaskConfig.ASYNC_REQUEST_TASK_CHANGE_FLAG_KEY)) {
            // Core thread count
            Integer corePoolSizeOld = executorService.getCorePoolSize();
            if (!corePoolSize.equals(corePoolSizeOld)) {
                executorService.setCorePoolSize(corePoolSize);
            }
            // Maximum thread count
            Integer maximumPoolSizeOld = executorService.getMaximumPoolSize();
            if (!maximumPoolSize.equals(maximumPoolSizeOld)) {
                executorService.setMaximumPoolSize(maximumPoolSize);
            }
            // Thread idle timeout
            Long keepAliveTimeOld = executorService.getKeepAliveTime(TimeUnit.MINUTES);
            if (!keepAliveTime.equals(keepAliveTimeOld)) {
                executorService.setKeepAliveTime(keepAliveTime, TimeUnit.MINUTES);
            }
        }
    }
}

Thread‑Pool Metric Reporting

After Spring Boot 2.x, adding the spring-boot-starter-actuator dependency enables Prometheus integration, allowing custom business metrics to be exported.

<dependency>
    <groupId>cn.gov.zcy.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Using Micrometer's MeterRegistry , a custom Gauge is registered to report the current pool size:

@Component
public class MonitorFactory {
    @Resource
    private MeterRegistry meterRegistry;
    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    private ThreadPoolSizeMonitor threadPoolSizeMonitor = new ThreadPoolSizeMonitor(threadPoolExecutor);

    class ThreadPoolSizeMonitor implements ToDoubleFunction
{
        private ThreadPoolExecutor executor;
        private AtomicDouble monitor = new AtomicDouble(0);
        public Object getMonitor() { return monitor; }
        public ThreadPoolSizeMonitor(ThreadPoolExecutor executor) { this.executor = executor; }
        @Override
        public double applyAsDouble(Object o) {
            monitor.set(executor.getPoolSize());
            return monitor.get();
        }
    }

    @PostConstruct
    public void monitorThreadPool() {
        Gauge.builder("ReportBatchSignPool_poolSizeMonitor", threadPoolSizeMonitor.getMonitor(), threadPoolSizeMonitor)
            .register(meterRegistry);
    }

    @Scheduled(cron = "0 0/1 * * * ?")
    public void publishWatcher() {
        threadPoolSizeMonitor.applyAsDouble(null);
    }
}

Prometheus Metric Display

Metrics can be queried with Prometheus query language; see the official documentation for query basics.

Grafana Visualization

Grafana dashboards visualize the exported metrics, providing real‑time insight into thread‑pool health.

Alert Configuration

Grafana alerts are configured with notification channels and rules to trigger warnings when thread‑pool load exceeds thresholds.

Conclusion

The article demonstrates how developers can configure custom Prometheus metrics for a thread‑pool, achieve dynamic parameter tuning via Apollo, and build a complete monitoring‑alerting pipeline with Grafana, thereby improving system stability and proactively preventing issues.

MonitoringThreadPoolalertingprometheusSpringBootGrafana
政采云技术
Written by

政采云技术

ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.