动态轻量级线程池项目
动态线程池:
使用线程池ThreadPoolExecutor过程中你是否有以下痛点呢?
① 代码中创建了一个ThreadPoolExecutor,但是不知道参数设置多少比较合适。
② 凭经验设置参数值,上线后发现需要调整,改代码重新发布服务,非常麻烦。
③ 线程池相对开发人员来说是个黑盒,运行情况不能及时感知到,直到出现问题。
如果有以上痛点,动态可监控线程 池框架(DynamicTp)或许能帮助到你。如果看过 ThreadPoolExecutor的源码,大概可以知道它对核心参数基本都有提供set/get方法以及一些扩展方法, 可以在运行时动态修改、获取相应 的值,如图所示:
dynamic-tp简介:
官网:
首页 | dynamictp
基于配置中心的轻量级动态线程池,内置监控告警功能,集成常用中间件线程池管理,可通过SPI自定义扩展实现。
为何要引入配置中心?
现在大多数的互联网项目都会微服务化部署,有一套自己的服务治理体系,微服务组件中的分布式配置中心扮演的就是动态修改配置, 实时生效的角色。那么我们是否可以结合 配置中心来做运行时线程池参数的动态调整呢?
答案是肯定的,而且配置中心相对都是高可用的,使用它也不用过于担心配置推送失败这 类问题,而且也能减少研发动态线程池组件本身的难度和工作量。综上,可以总结出以下 的背景:
① 广泛性:在 Java 开发中,想要提高系统性能,线程池已经是一个90%以上开发都 会选择使用的基础工具。
② 不确定性:项目中可能会创建很多线程池,既有IO密集型的,也有CPU密集型的, 但线程池的参数并不好确定;需要有套机制在运行过程中动态去调整参数。
③ 无感知性:线程池运行过程中的各项指标一般感知不到;需要有套监控报警机制在事前、事中就能让开发人员感知到线程池的运行状况及时处理。
④ 高可用性:配置变更需要及时推送到客户端,需要有高可用的配置管理推送服务, 配置中心是现在大多数互联网系统都会使用的组件,与之结合可以极大提高系统可 用性。
功能介绍:
功能 | 描述 |
代码零侵入 | 改变了线程池以往的使用方式,所有配置均放在配置中心,服务启动时会从配置中心 拉取配置生成线程池对象放到Spring容器中,使用时直接从 Spring 容器中获取,对 业务代码零侵入 |
通知告警 | 提供多种报警维度(配置变更通知、活性报警、容量阈值报警、拒绝触发报警、任务 执行或等待超时报警),已支持企业微信、钉钉、飞书、邮件报警,同时提供 SPI 接口可自定义扩展实现 |
运行监控 | 定时采集线程池指标数据,支持通过MicroMeter、JsonLog日志输出、Endpoint三种 方式,可通过SPI接口自定义扩展实现 |
任务增强 | 提供任务包装功能,实现TaskWrapper接口即可,如:MdcTaskWrapper、 TtlTaskWrapper、SwTraceTaskWrapper,可以支持线程池上下文信息传递 |
多配置中心支持 | 基于主流配置中心实现线程池参数动态调整,实时生效,已支持Nacos、Apollo、 Zookeeper、Consul、Etcd、Polaris、ServiceComb,同时也提供SPI接口可自定义扩 展实现 |
轻量简单 | 基于SpringBoot实现,引入starter,接入只需简单4步就可完成,顺利3分钟搞定 |
中间件线程池管理 | 集成管理常用第三方组件的线程池,已集成 Tomcat、Jetty、Undertow、Dubbo、 RocketMq、Hystrix、Grpc、Motan、Okhttp3、Brpc、Tars、SofaRpc、RabbitMq 等组件的线程池管理(调参、监控报警) |
多模式 | 提供了增强线程池 DtpExecutor,IO密集型场景使用的线程池 EagerDtpExecutor, 调度线程池 ScheduledDtpExecutor,有序线程池 OrderedDtpExecutor,可以根据业 务场景选择合适的线程池 |
兼容性 | JUC普通线程池和Spring中的ThreadPoolTaskExecutor也可以被框架管理,@Bean定 义时加 @DynamicTp 注解即可 |
可靠性 | 框架提供的线程池实现了Spring生命周期方法,可以在Spring容器关闭前尽可能多的 处理队列中的任务 |
高可扩展 | 框架核心功能都提供 SPI 接口供用户自定义个性化实现(配置中心、配置文件解析、 通知告警、监控数据采集、任务包装等等) |
线上大规模应用 | 参考《Java线程池实现原理及其在美团业务中的实践》和《动态线程池在转转平台的 实践》,美团及转转内部已经有该理论成熟的应用经验 |
模块划分:
模块名称 | 描述 |
配置变更监听 | ① 监听特定配置中心的指定配置文件(已实现 Nacos、Apollo、Zookeeper、Consul、 Etcd、Polaris、ServiceComb),可通过内部提供的SPI接口扩展其他实现 ② 解析配置文件内容,内置实现 yml、properties、json 配置文件的解析,可通过内 部提供的SPI接口扩展其他实现 ③ 通知线程池管理模块实现参数的刷新 |
线程池管理 | ① 服务启动时从配置中心拉取配置,生成线程池实例注册到内部线程池注册中心以及 Spring容器中 ② 接收配置监听模块的刷新事件,实现线程池参数的刷新 ③ 代码中通过依赖注入(推荐)或者 DtpRegistry.getDtpExecutor() 方法根据线程池 名称来获取线程池实例 |
第三方组件 线程池管理 | ① 利用Spring的事件机制和核心逻辑解耦,服务启动获取第三方中间件的线程池,被 框架管理起来,已集成 Tomcat、Jetty、Undertow、Dubbo、RocketMq、Hystrix、 Grpc、Motan、Okhttp3、Brpc、Tars、SofaRpc、RabbitMq 等组件线程池管理 ② 接受参数刷新、指标收集、通知报警事件,进行相应的处理 |
监控 | 实现监控指标采集以及输出,已支持以下三种方式,也可通过内部提供的SPI接口扩展其 他实现 ① 以JsonLog输出到磁盘指定目录,可以自己采集解析日志,存储展示 ② 以Micrometer采集,引入 Micrometer 相关依赖,暴露相关端点,采集指标数据, 结合Grafana做监控大盘 ③ 暴露自定义Endpoint端点(dynamic-tp),可通过http方式实时访问 |
通知告警 | ① 线程池主要参数变更通知 ② 阻塞队列容量达到设置的告警阈值 ③ 线程池活性达到设置的告警阈值 ④ 触发拒绝策略告警,格式:A/B A:该报警项前后两次报警区间累加数量 B:该报警项累计总数 ⑤ 任务执行超时告警,格式:A/B A:该报警项前后两次报警区间累加数量 B:该报警项累计总数 ⑥ 任务等待超时告警,格式:A/B A:该报警项前后两次报警区间累加数量 B:该报警项累计总 |
代码结构:
package | 描述 |
adapter | 主要是适配第三方组件的线程池管理,目前已经实现的有SpringBoot内置的三大web容器 (Tomcat、Jetty、Undertow)、Dubbo、RocketMq、Hystrix、Grpc、Motan、Okhttp3、 Brpc、Tars、SofaRpc、RabbitMq的线程池管理,后续会接入其他常用组件的线程池管理 |
common | 主要是一些各个模板都会用到的类,解耦依赖,复用代码,大家日常开发中可能也经常会 这样组织代码 |
core | 该框架的核心代码都在这个模块里,包括动态调整参数,监控报警,以及串联整个项目流 程都在此处 |
example | 提供一个简单使用示例,方便使用者参照 |
extension | 放一些扩展功能实现,比如基于redis的流控扩展、邮件发送扩展、skywalking上下文传递 扩展等 |
logging | 用于配置框架内部日志的输出,目前主要用于输出线程池监控指标数据到指定文件 |
starter | 提供独立功能模块的依赖封装、自动配置等相关 |
test | 主要是一些单元测试 |
DynamicTP技术架构图
动态线程池在大厂中的应用:
Java线程池实现原理及其在美团业务中的实践:
Java线程池实现原理及其在美团业务中的实践 - 美团技术团队
动态线程池在转转平台的实践:
动态线程池在转转平台的实践
环境搭建:
启动nacos服务:
进入到nacos\bin目录下:startup.cmd -m standalone
访问nacos:http://localhost:8848/nacos/
初始账号密码均为nacos
启动redis:
安装Node-Exporter
(前提:安装了Docker,Docker安装参考:)
相关文章:

动态轻量级线程池项目
动态线程池: 使用线程池ThreadPoolExecutor过程中你是否有以下痛点呢? ① 代码中创建了一个ThreadPoolExecutor,但是不知道参数设置多少比较合适。 ② 凭经验设置参数值,上线后发现需要调整,改代码重新发布服务&…...

【AI知识点】批归一化(Batch Normalization)
更多AI知识点总结见我的专栏:【AI知识点】 AI论文精读、项目和一些个人思考见我另一专栏:【AI修炼之路】 有什么问题、批评和建议都非常欢迎交流,三人行必有我师焉😁 批归一化(Batch Normalization,BN&…...
【低代码】前端低代码开发日记2:遇到的问题(1)双向绑定
在前期的快速迭代阶段,虽然界面有些杂乱,但整体功能尚能凑合运行。真正让人头疼的,还是接下来几个关键功能的实现。 遇到的问题 双向绑定 在Vue中,v-model提供了方便的双向绑定功能,它是modelValue属性和onUpdate:m…...

10.9作业
1、鼠标和键盘事件 #include "widget.h" #include "ui_widget.h" #include <QDebug> #include <QMouseEvent>widget::widget(QWidget *parent): QWidget(parent), ui(new Ui::widget) {ui->setupUi(this);this->setWindowFlag(Qt::Fram…...
Go 语言中的错误和异常:设计理念与优势
Go 语言中的错误和异常:设计理念与优势 在软件开发中,错误处理是一个至关重要的环节。不同的编程语言对于错误和异常的处理方式各有不同。Go 语言将错误和异常进行了明确区分,这种设计理念带来了许多独特的优势。本文将深入探讨 Go 语言中错误…...

sqli-labs less-20 less-21 less-22 cookie注入
COOKIE 作用:是由网络服务器存储在你电脑硬盘上的一个txt类型的小文件,它和你的网络行为有关,记录了当前用户的状态 形式:keyvalue 例如:当我们登录某个账号后,服务器会在cookies进行记录 个人理解…...

IDEA下“File is read-only”可能原因及“找不到或无法加载主类”问题的解决
1.File is read-only”可能原因 写代码时想要修改这个静态变量的值,把这个语句注释掉,发现在这个文件中File is read-only无法编辑修改,于是想去掉这个状态 网上查看的解释大多是在File栏目或File->File Properties下可以找到Make File W…...

MySQL【知识改变命运】03
表的基本操作 1:查看所有表2:创建表3:查看表结构4:修改表5: 删除表 前言:我们先了解一个知识: MySQL安装后会有MySQL服务——管理多个库——每个库管理多个表——每个表管理多行数据——数据行由…...

【测试】BUG篇——BUG
bug的概念 定义:⼀个计算机bug指在计算机程序中存在的⼀个错误(error)、缺陷(flaw)、疏忽(mistake)或者故障(fault),这些bug使程序⽆法正确的运⾏。Bug产⽣于程序的源代码或者程序设计阶段的疏忽或者错误。 准确的来说: 当且仅当规格说明&am…...

【高阶数据结构】深度探索二叉树进阶:二叉搜索树概念及其高效实现
高阶数据结构相关知识点可以通过点击以下链接进行学习一起加油! 本章是高阶数据结构笔记的第一篇文章,将分享二叉搜索树的进阶概念及其高效实现的相关知识,欢迎大家阅读! 🌈个人主页:是店小二呀 dz…...

上传本地项目到GitHub远程仓库(极简洁操作版)
第一步:在GitHub创建一个空的仓库 第二步:将仓库克隆(下载)到本地 第三步:将你要上传的所有文件放到这个克隆的仓库文件夹中 第四步:通过git add .将待上传文件添加到暂存区 此时,可以通过git …...
在安卓中使用 `mobile-ffmpeg` 压缩后的视频,浏览器在线播放提示“没有找到支持的视频格式和 MIME 类型”的解决方案
在安卓中使用 mobile-ffmpeg 压缩后的视频,浏览器在线播放提示“没有找到支持的视频格式和 MIME 类型”的解决方案 你可能在安卓开发中使用了 mobile-ffmpeg 进行视频压缩,而当你尝试在浏览器中在线播放压缩后的视频时,看到提示:…...

C语言指针plus版练习
上期我们讲了进阶的指针,本期内容我们来强化一下上期学的内容 一、字符串左旋 实现一个函数,可以左旋字符串中的k个字符。 1.1 分析题目 假设字符串为abcde,左旋一个以后就变成bcdea,就是把第一个字符移到一个新的变量里面&#…...

Kafka 快速入门
目录 介绍 KafKa 相关术语 编辑 Kafka的工作流程 生产者向kafka发送数据的流程 Kafka选择分区的模式 Kafka选择分区的模式 数据消费 kafka的文件存储机制 topic、partition和segment 存储和查找message的过程 数据写入过程 数据查找过程 注意事项 kafka管理UI …...
探索人们最喜爱的AI工具及其应用影响
探索人们最喜爱的AI工具及其应用影响 在科技飞速发展的时代,人工智能(AI)技术正在改变我们的生活和工作方式。越来越多的人开始使用AI工具来提高效率、简化流程和推动创新。那么,在众多的AI工具中,哪些是人们最喜欢的…...
c语言位域详解
一、什么是位域 位域是一种可以让结构体的成员变量以位为单位进行存储和操作的特性。位域允许我们精确控制数据的存储方式,而不像普通的整型变量那样固定使用系统规定的字节大小。 通过位域,我们可以在一个整型数据中指定具体的位数来表示某些信息。比…...
如何修改Spring Boot内置容器默认端口
默认情况下,Spring Boot 应用程序在嵌入式 Tomcat 服务器上启动,并监听默认端口 8080。如果您需要将默认的嵌入式服务器端口更改为其他端口号,可以使用以下几种方法之一: 嵌入式服务器配置命令行参数属性文件 在代码里以编程方式…...

STM32自动下载电路分享及注意事项
文章目录 简介ISP下载启动配置 USB转串口芯片CH340C手动isp下载自动isp下载RTS、DTR电平变化分析注意事项 简介 在嵌入式开发中,使用STM32下载程序,可以通过仿真器下载,也可以通过串口下载。在stm32串口下载时,我们需要手动配置启…...
【深度学习基础模型】极限学习机(Extreme Learning Machines, ELM)详细理解并附实现代码。
【深度学习基础模型】极限学习机(Extreme Learning Machines, ELM)详细理解并附实现代码。 【深度学习基础模型】极限学习机(Extreme Learning Machines, ELM)详细理解并附实现代码。 文章目录 【深度学习基础模型】极限学习机&a…...
把交换机的两个接口连接起来会怎么样?
当把交换机的两个接口连接起来时,可能会产生网络风暴,具体情况如下: 一、形成环路的过程 如果将交换机的两个端口直接连接,就会在网络中形成一个物理环路。例如,假设交换机有端口 A 和端口 B,用一根网线将…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...