Backend Development 9 min read

Implementing a Dynamic Thread Pool with Nacos in Spring Cloud

This article demonstrates how to build a dynamically configurable thread pool in a Spring Cloud backend by using Nacos as a configuration center, covering dependency setup, YAML files, Java implementation, controller exposure, testing steps, and practical tips for runtime adjustments.

Architect
Architect
Architect
Implementing a Dynamic Thread Pool with Nacos in Spring Cloud

In backend development, thread pool parameters are often tuned manually, which is costly because changes usually require a service restart. Placing the thread pool configuration on a platform side allows developers to adjust core and maximum thread counts dynamically.

The example uses Nacos as a service configuration center to modify the core and maximum thread numbers of a thread pool at runtime.

1. Dependencies

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2021.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2021.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

2. YAML Configuration

bootstrap.yml

server:
  port: 8010
# Application name (used as service name in Nacos)
spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        namespace: public
        server-addr: 192.168.174.129:8848
      config:
        server-addr: 192.168.174.129:8848
        file-extension: yml

application.yml

spring:
  profiles:
    active: dev

Bootstrap has higher priority than application.yml, ensuring Nacos configuration is loaded before the Spring Boot application starts.

3. Nacos Configuration

Create a configuration in the Nacos console. The Data ID follows the pattern ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension} , e.g., order-service-dev.yml . Only two parameters are set: core.size and max.size .

4. Dynamic Thread Pool Implementation

@RefreshScope
@Configuration
public class DynamicThreadPool implements InitializingBean {
    @Value("${core.size}")
    private String coreSize;
    @Value("${max.size}")
    private String maxSize;
    private static ThreadPoolExecutor threadPoolExecutor;
    @Autowired
    private NacosConfigManager nacosConfigManager;
    @Autowired
    private NacosConfigProperties nacosConfigProperties;
    @Override
    public void afterPropertiesSet() throws Exception {
        threadPoolExecutor = new ThreadPoolExecutor(Integer.parseInt(coreSize), Integer.parseInt(maxSize), 10L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(10),
                new ThreadFactoryBuilder().setNameFormat("c_t_%d").build(),
                new RejectedExecutionHandler() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                        System.out.println("rejected!");
                    }
                });
        // Listen to Nacos config changes
        nacosConfigManager.getConfigService().addListener("order-service-dev.yml", nacosConfigProperties.getGroup(),
                new Listener() {
                    @Override
                    public Executor getExecutor() { return null; }
                    @Override
                    public void receiveConfigInfo(String configInfo) {
                        System.out.println(configInfo);
                        changeThreadPoolConfig(Integer.parseInt(coreSize), Integer.parseInt(maxSize));
                    }
                });
    }
    public String printThreadPoolStatus() {
        return String.format("core_size:%s,thread_current_size:%s;thread_max_size:%s;queue_current_size:%s,total_task_count:%s",
                threadPoolExecutor.getCorePoolSize(), threadPoolExecutor.getActiveCount(),
                threadPoolExecutor.getMaximumPoolSize(), threadPoolExecutor.getQueue().size(),
                threadPoolExecutor.getTaskCount());
    }
    public void dynamicThreadPoolAddTask(int count) {
        for (int i = 0; i < count; i++) {
            int finalI = i;
            threadPoolExecutor.execute(() -> {
                try {
                    System.out.println(finalI);
                    Thread.sleep(10000);
                } catch (InterruptedException e) { e.printStackTrace(); }
            });
        }
    }
    private void changeThreadPoolConfig(int coreSize, int maxSize) {
        threadPoolExecutor.setCorePoolSize(coreSize);
        threadPoolExecutor.setMaximumPoolSize(maxSize);
    }
}

5. Controller for Testing

@RestController
@RequestMapping("/threadpool")
public class ThreadPoolController {
    @Autowired
    private DynamicThreadPool dynamicThreadPool;
    @GetMapping("/print")
    public String printThreadPoolStatus() {
        return dynamicThreadPool.printThreadPoolStatus();
    }
    @GetMapping("/add")
    public String dynamicThreadPoolAddTask(@RequestParam int count) {
        dynamicThreadPool.dynamicThreadPoolAddTask(count);
        return String.valueOf(count);
    }
}

6. Testing Steps

Start the application and call http://localhost:8010/threadpool/print to view current thread pool settings.

Invoke http://localhost:8010/threadpool/add?count=20 to add 20 tasks, then re‑print the status. Adjust the Nacos configuration (e.g., core size to 50, max size to 100) when tasks are rejected, and observe the pool adapting without restart.

7. Summary

The article provides a simple implementation of a dynamic thread pool whose core and maximum thread counts can be changed at runtime via Nacos. For production‑grade solutions, refer to Meituan’s detailed article on Java thread‑pool practices and integrate monitoring and alerting.

BackendJavadynamic-configurationThreadPoolNacosSpring Cloud
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

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.