基于 Nacos Config 事件监听 动态调整线程池参数

article/2025/10/18 2:22:51

一、Nacos Config 事件监听

在实际项目中一般都会使用线程池解决一些异步并发问题,不过线程池核心参数很大程度上一次性进行设置,但系统运行起来总有可能出现各种各样的问题,如果修改线程池的参数则一般需要重启项目,对于生产环境而言有时无法进行重启,这种情况下就需要我们做成可动态调节的线程池。以应对突发情况。

在微服务项目中,目前使用 Nacos 作为配置中心已经是非常普遍的现象,得益于 Nacos 的灵活性以及稳定性,本文我们基于 Nacos Config 配置能力,将线程池的核心参数配置到 Nacos 中,并通过Nacos Config 的事件监听机制,触发动态参数调节。

实验开始前,需要安装好 Nacos 服务:

在这里插入图片描述

线程池这里使用 springframework 提供的 ThreadPoolTaskExecutor ,并通过其自带的方法进行动态调节:

在这里插入图片描述

二、准备测试项目并创建配置文件

首先创建一个 SpringBoot 项目,并引入 nacos config 的依赖,这里为了方便操作属性 ,同时引入 lombokSpring Cloud Alibaba 版本使用的 2.2.6.RELEASE

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.6.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>

创建 bootstrap.yml 文件增加 nacos config 的配置,注意这里 application.namedemo-service ,下面创建配置文件命名时需要注意。

spring:application:name: demo-serviceprofiles:active: thread # 引入thread配置cloud:nacos:discovery:server-addr: 192.168.244.1:8848config:server-addr: 192.168.244.1:8848file-extension: yaml

这里单独引入一个 thread 配置,关于线程的配置都放在这里,文件名应该为 demo-service-thread.yaml

Nacos 创建 demo-service.yml 主配置文件,将服务的端口放在这里 :

server:port: 8082

在这里插入图片描述

接着创建 demo-service-thread.yaml 文件,声明出核心线程数、最大线程数、线程保持时间、以及队列的存储个数

thread:corePoolSize: 25maxPoolSize: 30keepAliveSeconds: 4queueCapacity: 200

在这里插入图片描述
在这里插入图片描述

二、声明线程池

首先对上面的配置文件,声明一个 Properties 接收参数:

@Data
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "thread")
public class ThreadPoolProperties {/*** 核心线程数*/private Integer corePoolSize;/*** 最大线程数*/private Integer maxPoolSize;/*** 线程保持时间 秒*/private Integer keepAliveSeconds;/*** 队列的存储个数*/private Integer queueCapacity;}

使用参数声明线程池,其中提供出调整线程池参数,和打印当前参数方法:

@Data
@Configuration
public class ThreadPoolConfig {@Resource(name = "dynamic_thread_pool")ThreadPoolTaskExecutor executor;@Bean(value = "dynamic_thread_pool")public ThreadPoolTaskExecutor dynamicThreadPool(ThreadPoolProperties properties) {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(properties.getCorePoolSize());executor.setMaxPoolSize(properties.getMaxPoolSize());executor.setKeepAliveSeconds(properties.getKeepAliveSeconds());executor.setQueueCapacity(properties.getQueueCapacity());executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());return executor;}/*** 重新设置参数*/public void restThreadPool(ThreadPoolProperties properties) {executor.setCorePoolSize(properties.getCorePoolSize());executor.setMaxPoolSize(properties.getMaxPoolSize());executor.setKeepAliveSeconds(properties.getKeepAliveSeconds());executor.setQueueCapacity(properties.getQueueCapacity());}/*** 打印线程池参数*/public void printParam() {System.out.println("当前核心线程数:" + executor.getCorePoolSize());System.out.println("当前最大线程数:" + executor.getMaxPoolSize());System.out.println("当前线程保持时间:" + executor.getKeepAliveSeconds());}}

三、添加 demo-service-thread.yaml 文件的监听

添加监听,这里我用的 PropertiesListener ,可以将修改后的配置,映射为 Properties 对象,如果想要拿到修改后配置内容的字符串可以使用 AbstractListenerListener

@Component
public class NacosListener implements ApplicationRunner {@ResourceNacosConfigManager nacosConfigManager;@ResourceNacosConfigProperties nacosConfigProperties;@ResourceThreadPoolConfig threadPoolConfig;@Overridepublic void run(ApplicationArguments args) throws Exception {System.out.println("初始线程状态:");threadPoolConfig.printParam();//配置修改监听nacosConfigManager.getConfigService().addListener("demo-service-thread.yaml", nacosConfigProperties.getGroup(),new PropertiesListener(){@Overridepublic void innerReceive(Properties properties) {System.out.println("配置被修改,重新调整线程池!");ThreadPoolProperties poolProperties = new ThreadPoolProperties();poolProperties.setCorePoolSize(Integer.parseInt(properties.getProperty("corePoolSize")));poolProperties.setMaxPoolSize(Integer.parseInt(properties.getProperty("maxPoolSize")));poolProperties.setKeepAliveSeconds(Integer.parseInt(properties.getProperty("keepAliveSeconds")));poolProperties.setQueueCapacity(Integer.parseInt(properties.getProperty("queueCapacity")));System.out.println("开始重新调整线程池...");threadPoolConfig.restThreadPool(poolProperties);System.out.println("调整之后线程池的参数:");threadPoolConfig.printParam();}});}
}

这里需要注意下,我在触发监听后,手动获取的参数,上面细心地会发现,其实ThreadPoolProperties 已经加了 @RefreshScope 会自动刷新的,那这里为啥还要手动解析呢,答案就是配置更新后,会首先触发这里的监听,如果在监听中直接调用调整方法,使用 ThreadPoolProperties 的话有可能还是原来的参数,保险起见这里获取一下。

四、测试

启动项目,可以看到初始的参数:

在这里插入图片描述

下面修改最大线程数为 50

在这里插入图片描述

发布后,观察日志:

在这里插入图片描述

线程池的最大线程已经被调整为 50


http://chatgpt.dhexx.cn/article/cgsumctI.shtml

相关文章

一文搞懂Java自定义线程池参数

背景: 线程是一个开发经常使用的东西&#xff0c;但是实际工作中很少有新建一个线程去执行任务&#xff0c;线程的创建和销毁都会耗费资源&#xff0c;我们一般都会用线程池来完成线程的创建和销毁。 多说一句 JDK自带的线程池不建议大家去使用&#xff0c;每个都存在资源的…

线程池参数调优

ThreadPoolExecutor ThreadPoolExecutor构造函数的五大参数 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, work…

线程池参数和状态详解

线程池详解 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)线程池的构造函数&#xff0c;参数详解&#xff1a;…

Java线程池参数、执行流程及线程数配置建议

1. 线程池参数详解 corePoolSize&#xff1a;线程池中常驻核心线程数&#xff1b;maximumPoolSize&#xff1a;线程池能够容纳同时执行的最大线程数&#xff1b;keepAliveTime&#xff1a;多余的空闲线程存活时间&#xff1b;unit&#xff1a;keepAliveTime的时间单位&#xf…

tomcat线程池参数

tomcat线程池executor配置参数 详解tomcat的连接数与线程池

线程池参数及队列

线程池中各个参数的含义 参数名含义corePoolSize核心线程数maximumPoolSize最大线程数keepAliveTime时间单位空闲线程的存活时间workQueue用于存放任务的队列threadFactory线程工厂、用来创建新线程handler处理别拒绝的任务 corePoolSize是核心线程数&#xff0c;也就是常驻线…

Java线程池参数分析

线程池组成 创建线程池 创建线程池通过Executors的工厂方法来创建线程池实例。 实际上Executors创建的线程池实例最终都是通过实例化配置不同参数的ThreadPoolExecutor对象。 public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecuto…

java线程池参数_java线程池参数设置原则,如何设置线程池参数比较合理?

线程池的参数应该怎样设置呢?相信对于很多的人来说这也是一个比较难的问题&#xff0c;下面就让我们一起来解决一下&#xff0c;究竟应该如何设置线程池的参数才是最合理的吧! 首先在设置参数的时候&#xff0c;有以下的几点是我们需要考虑到的! 1、下游系统抗并发的能力 多线…

线程池参数如何设置?

前言 着计算机行业的飞速发展&#xff0c;摩尔定律逐渐失效&#xff0c;多核CPU成为主流。使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器。J.U.C提供的线程池&#xff1a;ThreadPoolExecutor类&#xff0c;帮助开发人员管理线程并方便地执行并行任务。了解并合理…

动态调整线程池参数实践

欢迎大家关注我的微信公众号【老周聊架构】&#xff0c;Java后端主流技术栈的原理、源码分析、架构以及各种互联网高并发、高性能、高可用的解决方案。 一、线程池遇到的挑战 我们上一篇 《一文读懂线程池的实现原理 》已经从线程池如何维护自身状态、线程池如何管理任务、线程…

线程池参数及配置

线程池-线程池参数及配置 在实际项目中线程的应用都会使用线程池来管理&#xff0c;线程池的常用参数及配置学习记录。 目录 线程池-线程池参数及配置 一、线程池 1、线程池的优势 二、线程池常用参数 ThreadPoolExecutor 1. corePoolSize&#xff1a;核心线程数 2. que…

线程池7个参数描述

所谓的线程池的 7 大参数是指&#xff0c;在使用 ThreadPoolExecutor 创建线程池时所设置的 7 个参数&#xff0c;如以下源码所示&#xff1a; public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable&…

Java线程池七个参数详解

java多线程开发时&#xff0c;常常用到线程池技术&#xff0c;这篇文章是对创建java线程池时的七个参数的详细解释。 从源码中可以看出&#xff0c;线程池的构造函数有7个参数&#xff0c;分别是corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory…

【Android UI】贝塞尔曲线 ② ( 二阶贝塞尔曲线公式 | 三阶贝塞尔曲线及公式 | 高阶贝塞尔曲线 )

文章目录 一、二阶贝塞尔曲线公式二、三阶贝塞尔曲线三、高阶贝塞尔曲线 贝塞尔曲线参考 : https://github.com/venshine/BezierMaker 一、二阶贝塞尔曲线公式 二阶贝塞尔曲线公式如下 : B ( t ) ( 1 − t ) 2 P 0 2 t ( 1 − t ) P 1 t 2 P 2 , t ∈ [ 0 , 1 ] B(t) (1- t…

浅谈贝塞尔曲线

浅谈贝塞尔曲线 前段时间做了一个手写板功能的东西&#xff0c;其中手写部分用二次贝塞尔曲线完成&#xff0c;今天就来总结一下贝塞尔曲线在Android中的应用&#xff0c;先简单介绍各阶贝塞尔曲线的原理&#xff0c;然后实现通过贝塞尔曲线实现波浪线功能&#xff0c;感兴趣的…

View系列:贝塞尔曲线专栏:绘制二阶贝塞尔曲线(二)

1&#xff1a;Android贝塞尔曲线Api 作用相关Api备注移动起点moveTo移动下一次操作的起点位置连接直线lineTo添加上一个点到当前点的直线Path贝塞尔曲线qyadTo / cubicTo分别为绘制二次和三次贝塞尔曲线的方法闭合路径close从第一个点连接到最后一个点&#xff0c;形成一个闭合…

贝塞尔曲线原理

1 前言 贝塞尔曲线 (Bzier curve) 由法国数学家 Pierre Bzier 于 1962 年提出的一种矢量曲线&#xff0c;广泛应用于工程绘图、动画设计等领域。贝塞尔曲线是一种运动轨迹曲线&#xff0c;由 n 个点在 n 条线段上匀速运动&#xff08;不同线段上的速度可能不同&#xff09;&…

贝塞尔曲线简单介绍

什么是贝塞尔曲线&#xff1f; Bzier curve(贝塞尔曲线) 是应用于二维图形应用程序的数学曲线。 曲线定义&#xff1a;起始点、终止点&#xff08;也称锚点&#xff09;、控制点。通过调整控制点&#xff0c;贝塞尔曲线的形状会发生变化。 1962年&#xff0c;法国数学家Pierre…

贝塞尔曲线原理简述

1. 曲线算法简介&#xff1a; 贝塞尔曲线应用于二维图形应用程序的数学曲线&#xff0c;由一组控制点的向量来确定&#xff0c;给定的控制点按顺序连接构成控制多边形&#xff0c;贝塞尔曲线逼近这个多边形&#xff0c;进而通过调整控制点坐标改变曲线的形状。 2. 绘制曲线 …

贝塞尔曲线动画C++简单实践

目录 贝塞尔曲线简介一阶贝塞尔二阶贝塞尔三阶贝塞尔N阶贝塞尔曲线 贝塞尔曲线在动画中的应用实践求曲线散点坐标将曲线应用到动画动画框架cmd动画窗口动画 完整代码示例代码核心类代码BezierCurveAnimatorConsole 参考资料 贝塞尔曲线简介 由于用计算机画图大部分时间是操作鼠…