当前位置: 首页 > news >正文

SpringBoot + Nacos 实现动态化线程池

1.背景

在后台开发中,会经常用到线程池技术,对于线程池核心参数的配置很大程度上依靠经验。然而,由于系统运行过程中存在的不确定性,我们很难一劳永逸地规划一个合理的线程池参数。

在对线程池配置参数进行调整时,一般需要对服务进行重启,这样修改的成本就会偏高。一种解决办法就是,将线程池的配置放到平台侧,运行开发同学根据系统运行情况对核心参数进行动态配置。

本文以Nacos作为服务配置中心,以修改线程池核心线程数、最大线程数为例,实现一个简单的动态化线程池。

2.code

1.依赖
<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.配置yml文件

bootstrap.yml

server:port: 8090# 应用名称(nacos会将该名称当做服务名称)
spring:application:name: order-servicecloud:nacos:discovery:namespace: publicserver-addr: localhost:8848config:server-addr: localhost:8848file-extension: yml

application.yml

spring:profiles:active: dev

为什么要配置两个yml文件?

springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application。

nacos在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后才能保证项目的正常启动。

3.nacos配置

登录到nacos管理页面,新建配置,如下图所示

注意Data ID的命名格式为,${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension} ,在本文中,Data ID的名字就是order-service-dev.yml

配置详情

这里我们只配置了两个参数,核心线程数量和最大线程数。

4.线程池配置和nacos配置变更监听
@RefreshScope
@Configuration
public class DynamicThreadPool implements InitializingBean {@Value("${core.size}")private String coreSize;@Value("${max.size}")private String maxSize;private static ThreadPoolExecutor threadPoolExecutor;@Autowiredprivate NacosConfigManager nacosConfigManager;@Autowiredprivate NacosConfigProperties nacosConfigProperties;@Overridepublic void afterPropertiesSet() throws Exception {//按照nacos配置初始化线程池threadPoolExecutor = new ThreadPoolExecutor(Integer.parseInt(coreSize), Integer.parseInt(maxSize), 10L, TimeUnit.SECONDS,new LinkedBlockingQueue<>(10),new ThreadFactoryBuilder().setNameFormat("c_t_%d").build(),new RejectedExecutionHandler() {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {System.out.println("rejected!");}});//nacos配置变更监听nacosConfigManager.getConfigService().addListener("order-service-dev.yml", nacosConfigProperties.getGroup(),new Listener() {@Overridepublic Executor getExecutor() {return null;}@Overridepublic 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());}/*** 给线程池增加任务** @param count*/public void dynamicThreadPoolAddTask(int count) {for (int i = 0; i < count; i++) {int finalI = i;threadPoolExecutor.execute(new Runnable() {@Overridepublic void run() {try {System.out.println(finalI);Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}});}}/*** 修改线程池核心参数** @param coreSize* @param maxSize*/private void changeThreadPoolConfig(int coreSize, int maxSize) {threadPoolExecutor.setCorePoolSize(coreSize);threadPoolExecutor.setMaximumPoolSize(maxSize);}
}

这个代码就是实现动态线程池和核心了,需要说明的是:

  • @RefreshScope,这个注解用来支持nacos的动态刷新功能;

  • @Value("${max.size}")@Value("${core.size}"),这两个注解用来读取我们上一步在nacos配置的具体信息;同时,nacos配置变更时,能够实时读取到变更后的内容;

  • nacosConfigManager.getConfigService().addListener,配置监听,nacos配置变更时实时修改线程池的配置。

5.controller

为了观察线程池动态变更的效果,增加Controller类。

@RestController
@RequestMapping("/threadpool")
public class ThreadPoolController {@Autowiredprivate DynamicThreadPool dynamicThreadPool;/*** 打印当前线程池的状态*/@GetMapping("/print")public String printThreadPoolStatus() {return dynamicThreadPool.printThreadPoolStatus();}/*** 给线程池增加任务** @param count*/@GetMapping("/add")public String dynamicThreadPoolAddTask(int count) {dynamicThreadPool.dynamicThreadPoolAddTask(count);return String.valueOf(count);}
}
6.测试

启动项目,访问http://localhost:8090/threadpool/print打印当前线程池的配置。

可以看到,这个就是我们之前在nacos配置的线程数。

访问http://localhost:8090/threadpool/add?count=20增加20个任务。

重新打印线程池配置

可以看到已经有线程在排队了。

为了能够看到效果,我们多访问几次/add接口,增加任务数,在控制台出现拒绝信息时调整nacos配置。

此时,执行/add命令时,所有的线程都会提示rejected。

调整nacos配置,将核心线程数调整为50,最大线程数调整为100.

重新多次访问/add接口增加任务,发现没有拒绝信息了。这时,打印具体的线程状态,发现线程池参数修改成功。

相关文章:

SpringBoot + Nacos 实现动态化线程池

1.背景 在后台开发中&#xff0c;会经常用到线程池技术&#xff0c;对于线程池核心参数的配置很大程度上依靠经验。然而&#xff0c;由于系统运行过程中存在的不确定性&#xff0c;我们很难一劳永逸地规划一个合理的线程池参数。 在对线程池配置参数进行调整时&#xff0c;一…...

《Docker极简教程》--Dockerfile--Dockerfile的基本语法

Dockerfile是一种文本文件&#xff0c;用于定义Docker镜像的内容和构建步骤。它包含一系列指令&#xff0c;每个指令代表一个构建步骤&#xff0c;从基础镜像开始&#xff0c;逐步构建出最终的镜像。通过Dockerfile&#xff0c;用户可以精确地描述应用程序运行环境的配置、依赖…...

css中, grid-auto-rows: 怎样简写在grid:中

grid-auto-rows:100px; grid-template-columns:1fr 1fr; &#x1f446;可以写成&#x1f447; grid:auto-flow 100px / 1fr 1fr;在CSS Grid布局中&#xff0c;grid-auto-rows 属性用于指定自动生成的网格容器的行的大小。如果你想要将 grid-auto-rows 的值简写在 grid 属性中&a…...

@ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)

代码随想录算法训练营第8周&#xff08;C语言&#xff09;|Day53&#xff08;动态规划&#xff09; Day50、动态规划&#xff08;包含题目 ● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV &#xff09; 123.买卖股票的最佳时机III 题目描述 给定一个数组 price…...

算法-矩阵置零

1、题目来源 73. 矩阵置零 - 力扣&#xff08;LeetCode&#xff09; 2、题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1…...

xilinx除法器的使用

平台&#xff1a;Vivado2018.3. 芯片&#xff1a;xcku115-flva1517-2-i (active) 最近学习使用了xilinx除法器&#xff0c;在使用过程中出现了很多次除法器的结果和我预计的结果不一致&#xff0c;特此记录学习一下。 参考文件&#xff1a;pg151.下载地址 pg151-div-gen.pdf …...

算法沉淀——递归(leetcode真题剖析)

算法沉淀——递归 01.汉诺塔问题02.合并两个有序链表03.反转链表04.两两交换链表中的节点05.Pow(x, n) 递归是一种通过调用自身的方式来解决问题的算法。在递归算法中&#xff0c;问题被分解为更小的相似子问题&#xff0c;然后通过对这些子问题的解进行组合来解决原始问题。递…...

BERT模型中的input_ids和attention_mask参数

一、概述 1.1 input_ids 在BERT模型及其衍生体中&#xff0c;输入文本首先经过一个分词处理流程&#xff0c;其中文本被细分为单词或子单词&#xff08;subwords&#xff09;&#xff0c;每个分词随后映射到一个唯一的整数标识符。这些标识符组成了所谓的input_ids数组&#x…...

java+vue_springboot企业设备安全信息系统14jbc

企业防爆安全信息系统采用B/S架构&#xff0c;数据库是MySQL。网站的搭建与开发采用了先进的java进行编写&#xff0c;使用了vue框架。该系统从三个对象&#xff1a;由管理员、人员和企业来对系统进行设计构建。主要功能包括&#xff1a;个人信息修改&#xff0c;对人员管理&am…...

vulhub中Apache Log4j Server 反序列化命令执行漏洞复现(CVE-2017-5645)

Apache Log4j是一个用于Java的日志记录库&#xff0c;其支持启动远程日志服务器。Apache Log4j 2.8.2之前的2.x版本中存在安全漏洞。攻击者可利用该漏洞执行任意代码。 1.我们使用ysoserial生成payload&#xff0c;然后直接发送给your-ip:4712端口即可。 java -jar ysoserial-…...

基于python+django+vue.js开发的医院门诊管理系统/医疗管理系统

功能介绍 平台采用B/S结构&#xff0c;后端采用主流的Python语言进行开发&#xff0c;前端采用主流的Vue.js进行开发。 功能包括&#xff1a;医生管理、科室管理、护士管理、住院管理、药品管理、用户管理、日志管理、系统信息模块。 源码地址 https://github.com/geeeeeee…...

Linux文件系统笔记

文章目录 FILE SYSTEM软硬链接 动静态库 使用别人提供的库 FILE SYSTEM 文件的管理工作&#xff1a; 1.基础知识&#xff1a; 文件 属性 内容不是所有文件都会打开所有的打开的&#xff0c;未打开的文件会进行管理未打开文件&#xff0c;要能做到快速定位文件磁盘–物理存…...

vue封装el-table表格组件

先上效果图&#xff1a; 本文包含了具名插槽、作用域插槽、jsx语法三种&#xff1a; Render.vue&#xff08;很重要&#xff0c;必须有&#xff09;: <script> export default {name: "FreeRender",functional: true,props: {scope:Object,render: Functio…...

「Python系列」Python数据结构

文章目录 一、数据结构二、相关链接 一、数据结构 Python提供了多种内置的数据结构&#xff0c;这些数据结构在编程中非常有用。以下是Python中常见的一些数据结构&#xff1a; 列表&#xff08;List&#xff09;: 列表是Python中最常用的数据结构之一&#xff0c;它是一个有…...

MySQL多实例部署:从概念到实操的全面指南

目录 MySQL多实例管理 单实例 什么是多实例 多实例的好处 多实例的弊端 MySQL多实例用在哪些场景 资金紧张的公司 用户并发访问量不大的业务 大型网站也有用多实例 部署MySQL多实例 rpm和源码的优缺点 二进制方式安装mysql 准备二进制mysql运行所需的环境 准备多…...

C++学习Day07之虚函数和纯虚函数

目录 前言一、程序及输出1.1 虚函数1.2 纯虚函数1.2.1 定义、示例1.2.2 引入原因1.2.3 抽象类 二、分析与总结 前言 在 C 中&#xff0c;虚函数和纯虚函数是实现多态性的重要概念。虚函数是在基类中声明为虚函数的函数&#xff0c;在派生类中可以被重写&#xff0c;实现动态联…...

GZ036 区块链技术应用赛项赛题第9套

2023年全国职业院校技能大赛 高职组 “区块链技术应用” 赛项赛卷&#xff08;9卷&#xff09; 任 务 书 参赛队编号&#xff1a; 背景描述 随着异地务工人员的增多&#xff0c;房屋租赁成为一个广阔是市场&#xff1b;目前&#xff0c;现有技术中的房屋租赁是由…...

微服务—RabbitMQ高级(延迟消息)

本博客为个人学习笔记&#xff0c;学习网站&#xff1a;2023黑马程序员RabbitMQ入门到实战教程 高级篇章节 目录 延迟消息 死信交换机 延迟消息插件 下载安装 延迟交换机声明 ​编辑 发送延迟消息 订单状态同步问题 延迟消息 在电商的支付业务中&#xff0c;对于一些库…...

香港服务器如何取消windows的自动更新

大家用过电脑的人对windows系统的自动更新应该都不会陌生&#xff0c;其实香港服务器的使用也是一样的方法。为什么要对香港服 务器windows的自动更新进行关闭呢&#xff1f;其主要原因在于&#xff0c;有些更新是不能更新&#xff0c;一更新话&#xff0c;系统反而会变得不稳定…...

kali虚拟机桥接模式快速设置

第一步&#xff1a;选择 虚拟机 > 设置 > 虚拟机设置&#xff0c;设置桥接模式 不选择复制物理网络连接状态选项&#xff1a; 如果采用DHCP的方式来分配IP地址&#xff0c;当电脑网络从有线或无线网络之间进行移动时&#xff0c;DHCP会重新分配ip地址&#xff0c;即虚拟机…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

篇章二 论坛系统——系统设计

目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...