「使用线程池 ThreadPoolExecutor 过程中你是否有以下痛点呢?」 1.代码中创建了一个
ThreadPoolExecutor
,但是不知道那几个核心参数设置多少比较合适 2.凭经验设置参数值,上线后发现需要调整,改代码重启服务,非常麻烦 3.线程池相对开发人员来说是个黑盒,运行情况不能及时感知到,直到出现问题
如果你有以上痛点,动态可监控线程池(DynamicTp)或许能帮助到你。
如果看过 ThreadPoolExecutor
的源码,大概可以知道它对核心参数基本都有提供 set / get
方法以及一些扩展方法,可以在运行时动态修改、获取相应的值。
现在大多数的互联网项目其实都会微服务化部署,有一套自己的服务治理体系,微服务组件中的分布式配置中心扮演的就是动态修改配置, 实时生效的角色。那么我们是否可以结合配置中心来做运行时线程池参数的动态调整呢?答案是肯定的,而且配置中心相对都是高可用的, 使用它也不用过于担心配置推送出现问题这类事儿,而且也能减少研发动态线程池组件的难度和工作量。
「综上,可以总结出以下的背景」
「基于以上背景分析,我们对线程池 ThreadPoolExecutor 做一些扩展增强,主要实现以下目标」
1.实现对运行中线程池参数的动态修改,实时生效
2.实时监控线程池的运行状态,触发设置的报警策略时报警,报警信息推送办公平台
3.定时采集线程池指标数据,配合像 grafana 这种可视化监控平台做大盘监控
「经过多个版本的迭代,目前最新版本 v1.0.9 具有以下特性」 ✅
starter
,接入只需简单 4 步就可完成,顺利 3 分钟搞定MicroMeter
、JsonLog
日志输出、Endpoint
三种方式,可通过 SPI 接口自定义扩展实现TaskWrapper
接口即可,如 MdcTaskWrapper
、TtlTaskWrapper
、SwTraceTaskWrapper
,可以支持线程池上下文信息传递ThreadPoolTaskExecutor
也可以被框架监控,@Bean
定义时加 @DynamicTp
注解即可EagerDtpExecutor
线程池Nacos
、Apollo
、Zookeeper
、Consul
、Etcd
,同时也提供 SPI 接口可自定义扩展实现Tomcat
、Jetty
、Undertow
、Dubbo
、RocketMq
、Hystrix
、Grpc
等组件的线程池管理(调参、监控报警)框架功能大体可以分为以下几个模块
1.配置变更监听模块
2.服务内部线程池管理模块
3.三方组件线程池管理模块
4.监控模块
5.通知告警模块
Tomcat
、Jetty
、Undertow
)、Dubbo
、RocketMq
、Hystrix
、Grpc
的线程池管理, 后续会接入其他常用组件的线程池管理。1.监听特定配置中心的指定配置文件(已实现 Nacos
、Apollo
、Zookeeper
、Consul
、Etcd
),可通过内部提供的SPI接口扩展其他实现
2.解析配置文件内容,内置实现 yml
、properties
、json
配置文件的解析,可通过内部提供的 SPI 接口扩展其他实现
3.通知线程池管理模块实现参数的刷新
1.服务启动时从配置中心拉取配置,生成线程池实例注册到内部线程池注册中心以及 Spring 容器中
2.接受配置监听模块的刷新事件,实现线程池参数的刷新
3.代码中通过依赖注入(推荐)或者 DtpRegistry.getDtpExecutor()
方法根据线程池名称来获取线程池实例
1.服务启动获取第三方中间件的线程池,被框架管理起来
2.接受参数刷新、指标收集、通知报警事件,进行相应的处理
实现监控指标采集以及输出,默认提供以下三种方式,也可通过内部提供的 SPI 接口扩展其他实现
JsonLog
输出到磁盘,可以自己采集解析日志,存储展示MicroMeter
采集,引入 MicroMeter
相关依赖,暴露相关端点,采集指标数据,结合 Grafana
做监控大盘Endpoint
端点(dynamic-tp
),可通过 http 方式实时访问对接办公平台,实现通知告警功能,已支持钉钉、企微、飞书、邮件,可通过内部提供的 SPI 接口扩展其他实现,通知告警类型如下