当前位置: 首页 > 科技观察

使用Nacos实现动态线程池,非常实用!

时间:2023-03-18 14:53:49 科技观察

在后台开发中,经常会用到线程池技术,而线程池核心参数的配置很大程度上取决于经验。但是由于系统运行过程中的不确定性,我们很难一劳永逸地规划出一个合理的线程池参数。在调整线程池的配置参数时,一般需要重启服务,这样修改的成本会很高。一种解决方案是将线程池的配置放在平台端,运行开发者可以根据系统运行动态配置核心参数。本文以Nacos为服务配置中心,以修改线程池核心线程数和最大线程数为例,实现一个简单的动态线程池。代码实现1.依赖com.alibaba.cloudspring-cloud-starter-alibaba-nacos-discovery2021.1com.alibaba.cloudspring-cloud-starter-alibaba-nacos-config2021.1org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-复制代码starter2.配置yml文件bootstrap.yml:server:port:8010#应用名称(nacos会将该名称当做服务名称)spring:application:name:order-servicecloud:nacos:discovery:命名空间:公共服务器地址:192.168.174.129:8848config:server-addr:192.168.174.129:8848file-extension:ymlapplication.yml:spring:profiles:active:dev为什么要配置两个yml文件?springboot中配置文件的加载是有优先顺序的。bootstrap的优先级高于applicationnacos。项目初始化时,需要保证先从配置中心拉取配置,拉取配置后才能保证项目的正常启动。3、Nacos配置登录nacos管理页面,新建配置,如下图:注意DataID的命名格式为${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension},本文中DataID的名称为order-service-dev.yml。这里我们只配置两个参数,核心线程数和最大线程数。4.线程池配置和nacos配置变更监听@RefreshScope@ConfigurationpublicclassDynamicThreadPoolimplementsInitializingBean{@Value("${core.size}")privateStringcoreSize;@Value("${max.size}")privateStringmaxSize;私人静态ThreadPoolExecutorthreadPoolExecutor;@AutowiredprivateNacosConfigManagernacosConfigManager;@AutowiredprivateNacosConfigPropertiesnacosConfigProperties;@OverridepublicvoidafterPropertiesSet()throwsException{//点击nacos配置初始化线程池threadPoolExecutor=newThreadPoolExecutor(Integer.parseInt(coreSize),Integer.parseInt(maxSize),10L,TimeUnit.SECONDS,newLinkedBlockingQueue<>(10),newThreadFactoryBuilder().setNameFormat("c_t_%d").build(),newRejectedExecutionHandler(){@OverridepublicvoidrejectedExecution(Runnabler,ThreadPoolExecutor执行器){System.out.println("被拒绝了!");}});//nacos配置变化监听nacosConfigManager.getConfigService().addListener("order-service-dev.yml",nacosConfigProperties.getGroup(),newListener(){@OverridepublicExecutorgetExecutor(){returnnull;}@OverridepublicvoidreceiveConfigInfo(StringconfigInfo){//Configurationchange,修改线程池配置System.out.println(configInfo);changeThreadPoolConfig(Integer.parseInt(coreSize),Integer.parseInte(maxSize));}});}/***打印当前线程池的状态*/publicStringprintThreadPoolStatus(){returnString.format("core_size:%s,thread_current_size:%s;"+"thread_max_size:%s;queue_current_size:%s,总任务数:%s",threadPoolExecutor。getCorePoolSize(),threadPoolExecutor.getActiveCount(),threadPoolExecutor.getMaximumPoolSize(),threadPoolExecutor.getQueue().size(),threadPoolExecutor.getTaskCount());}/***给线程池增加任务**@paramcount*/publicvoiddynamicThreadPoolAddTask(intcount){for(inti=0;i