背景
在使用线程池的过程中,会出现一些痛点:
- 代码中创建了一个线程池,但是不知道那几个核心参数设置多少比较合适。
- 凭经验设置参数值,上线后发现需要调整,改代码重新发布服务,非常麻烦。
- 线程池相对开发人员来说是个黑盒,运行情况不能及时感知到,直到出现问题。
...
多线程使用的特点:
广泛性
在 Java 开发中,想要提高系统性能,线程池已经是一个 90% 以上开发都会选择使用的基础工具。
不确定性
项目中可能会创建很多线程池,既有 IO 密集型的,也有 CPU 密集型的,但线程池的参数并不好确定;需要有套机制在运行过程中动态去调整参数。
无感知性
线程池运行过程中的各项指标一般感知不到;需要有套监控报警机制在事前、事中就能让开发人员感知到线程池的运行状况,及时处理。
高可用性
配置变更需要及时推送到客户端,需要有高可用的配置管理推送服务,配置中心是现在大多数互联网系统都会使用的组件,与之结合可以极大提高系统可用性。
基于上面的一些情况,然后dynamic都可以很好个给予解决
Dynamic-tp
Dynamic-tp是什么?
Dynamic-tp是美团开源的一个基于配置中心的轻量级动态可监控线程池中间件,通过它可以很轻松的配置和监控线程的相关信息。
官方宣传的优点
动态调参
在运行时动态调整线程池参数,包括核心线程数、最大线程数、空闲线程超时时间、任务队列大小等。
通知报警
目前支持调参通知、活性、队列容量、拒绝策略、超时共六类通知报警维度,在运行时实时+定时检测,触发阈值进行推送。
运行监控
定时采集线程池运行指标数据,提供jsonlog、micrometer、endpoint三种指标数据采集方式,可灵活选择
三方包集成
集成三方中间件线程池管理,已接入dubbo、rocketmq、hystrix、grpc、tomcat、undertow、jetty、grpc、okhttp等组件线程池管理
官方的宣传功能特性
代码零侵入
我们改变了线程池以往的使用姿势,所有配置均放在配置中心,服务启动时会从配置中心拉取配置生成线程池对象放到 Spring 容器中,使用时直接从 Spring 容器中获取,对业务代码零侵入
通知告警
提供多种报警维度(配置变更通知、活性报警、容量阈值报警、拒绝触发报警、任务执行或等待超时报警),已支持企业微信、钉钉、飞书、邮件报警,同时提供 SPI 接口可自定义扩展实现
运行监控
定时采集线程池指标数据,支持通过 MicroMeter、JsonLog 日志输出、Endpoint 三种方式,可通过 SPI 接口自定义扩展实现
任务增强
提供任务包装功能,实现 TaskWrapper 接口即可,如 MdcTaskWrapper、TtlTaskWrapper、SwTraceTaskWrapper,可以支持线程池上下文信息传递
多配置中心支持
基于主流配置中心实现线程池参数动态调整,实时生效,已支持 Nacos、Apollo、Zookeeper、Consul、Etcd、Polaris、ServiceComb,同时也提供 SPI 接口可自定义扩展实现
中间件线程池管理
集成管理常用第三方组件的线程池,已集成 Tomcat、Jetty、Undertow、Dubbo、RocketMq、Hystrix、Grpc、Motan、Okhttp3、Brpc、Tars、SofaRpc、RabbitMq 等组件的线程池管理(调参、监控报警)
轻量简单
基于 SpringBoot 实现,引入 starter,接入只需简单 4 步就可完成,顺利 3 分钟搞定
多模式
提供了增强线程池 DtpExecutor,IO 密集型场景使用的线程池 EagerDtpExecutor,调度线程池 ScheduledDtpExecutor,有序线程池 OrderedDtpExecutor,可以根据业务场景选择合适的线程池
兼容性
JUC 普通线程池和 Spring 中的 ThreadPoolTaskExecutor 也可以被框架管理,@Bean 定义时加 @DynamicTp 注解即可
可靠性
框架提供的线程池实现 Spring 生命周期方法,可以在 Spring 容器关闭前尽可能多的处理队列中的任务
高可扩展
框架核心功能都提供 SPI 接口供用户自定义个性化实现(配置中心、配置文件解析、通知告警、监控数据采集、任务包装等等)
线上大规模应用
美团内部已经有该理论成熟的应用经验
dynamictp架构设计
接入使用教程
- 引入相应配置中心的依赖,maven 依赖见下述
- 配置中心配置线程池实例,配置文件见下述
- 启动类加 @EnableDynamicTp 注解
- 使用 @Resource 或 @Autowired 进行依赖注入,或通过 DtpRegistry.getDtpExecutor("name") 获取
- 通过以上 4 步就可以使用了
官方接入步骤:接入步骤 | dynamic-tp
Nacos集成接入
- 动态线程池配置文件,建议单独开一个文件放在 nacos 中,如:user-center-dtp-dev.yml
- 如果配置中心支持 yml 格式,建议最好使用 yml 文件配置,可读性、可操作性更友好
- 给出的是全配置项,使用不到的项或者使用默认值的项都可以删除,减少配置量
- 集成失败 90% 以上情况都是使用姿势有误 / 版本兼容问题,有版本兼容性问题可以提 Issues 或加群反馈。
- nacos-config-spring-boot-starter 0.2.10 及以下版本对应 springboot 2.3.12.RELEASE 及以下版本。0.2.11-beta 及以上版本对应 springboot 版本 2.4.0 及以上版本,具体看官方说明
官方nacos接入说明:nacos 应用接入 | dynamic-tp
总结
接入相对比较简单,使用起来也比较方便,需要调优的时候,直接修改nacos配置文件,然后重新发布即可。