Backend Development 7 min read

How to Dynamically Adjust Thread Pool Size with Nacos in Java

Learn how to integrate Nacos as a dynamic configuration center to modify Java thread pool sizes at runtime, covering dependency setup, initial Nacos configuration, custom listener implementation, thread pool usage, testing, and the benefits of adaptive scaling for production systems.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
How to Dynamically Adjust Thread Pool Size with Nacos in Java

Introduction

This article explores how to use Nacos as a dynamic configuration center to modify thread pool sizes online, passing the configuration to the application and listening for changes to adjust the pool dynamically, thereby improving flexibility and scalability.

Practical Example

Dependency Management

<code>&lt;properties&gt;
  &lt;nacos.version&gt;2.1.2&lt;/nacos.version&gt;
  &lt;yaml.version&gt;1.33&lt;/yaml.version&gt;
  &lt;java.version&gt;17&lt;/java.version&gt;
&lt;/properties&gt;
&lt;dependency&gt;
  &lt;groupId&gt;com.alibaba.nacos&lt;/groupId&gt;
  &lt;artifactId&gt;nacos-client&lt;/artifactId&gt;
  &lt;version&gt;${nacos.version}&lt;/version&gt;
  &lt;classifier&gt;pure&lt;/classifier&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;com.alibaba.nacos&lt;/groupId&gt;
  &lt;artifactId&gt;nacos-common&lt;/artifactId&gt;
  &lt;version&gt;${nacos.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;com.alibaba.nacos&lt;/groupId&gt;
  &lt;artifactId&gt;nacos-api&lt;/artifactId&gt;
  &lt;version&gt;${nacos.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;org.yaml&lt;/groupId&gt;
  &lt;artifactId&gt;snakeyaml&lt;/artifactId&gt;
  &lt;version&gt;${yaml.version}&lt;/version&gt;
&lt;/dependency&gt;</code>

Initial Nacos Configuration

Configure the core and maximum thread pool sizes in Nacos (e.g., coreSize and maximumPoolSize ).

Custom Nacos Listener

<code>public class NacosConfigListener {
  public void start() throws Exception {
    String serverAddr = "localhost:8848";
    String dataId = "dy-thread.yaml";
    String group = "dy";
    Properties properties = new Properties();
    properties.put("serverAddr", serverAddr);
    properties.put("username", "nacos");
    properties.put("password", "nacos");
    ConfigService configService = NacosFactory.createConfigService(properties);
    String content = configService.getConfig(dataId, group, 5000);
    System.out.println("Initial config:\n" + content);
    Yaml yaml = new Yaml();
    configService.addListener(dataId, group, new Listener() {
      public void receiveConfigInfo(String configInfo) {
        try {
          LinkedHashMap<String, Object> content = (LinkedHashMap<String, Object>) yaml.load(configInfo);
          System.out.println("Listener received change:" + content);
          LinkedHashMap<String, Object> dy = (LinkedHashMap<String, Object>) content.get("dy");
          Integer coreSize = (Integer) dy.get("coreSize");
          Integer maximumPoolSize = (Integer) dy.get("maximumPoolSize");
          DynamicThreadPoolConfig.pool.setMaximumPoolSize(maximumPoolSize);
          DynamicThreadPoolConfig.pool.setCorePoolSize(coreSize);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      @Override
      public Executor getExecutor() {
        return null;
      }
    });
  }
}
</code>

Thread Pool Usage

<code>public class DynamicThreadPoolConfig {
  public static final ThreadPoolExecutor pool = new ThreadPoolExecutor(
    2, 3, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100));

  public static void main(String[] args) throws Exception {
    new NacosConfigListener().start();
    var schedule = new ScheduledThreadPoolExecutor(1);
    schedule.scheduleAtFixedRate(() -> {
      System.out.println(
        "Core threads: " + pool.getCorePoolSize() +
        ", Max threads: " + pool.getMaximumPoolSize() +
        ", Active tasks: " + pool.getActiveCount()
      );
    }, 0, 3, TimeUnit.SECONDS);

    for (var i = 0; i < 100; i++) {
      pool.execute(() -> {
        try {
          System.out.println(Thread.currentThread().getName());
          TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      });
    }
  }
}
</code>

Testing

Run the program; the console initially shows the default pool values. Then modify the thread pool size via the Nacos UI and observe the console output reflecting the new configuration.

Conclusion

Dynamic modification of thread pool size is crucial for adapting to load variations, handling burst traffic, and enhancing system flexibility and scalability in production environments, thereby maintaining stability and performance while meeting evolving business demands.

backend developmentdynamic configurationNacosthread pool
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

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.