springcloud nacos动态线程池Dynamic tp配置接入实战详解
刨红薯的小羊竿尔 人气:0一、接入步骤
最近业务上需要把项目组几个微服务接入动态线程池框架Dynamic-tp监控,同时支持webhook机器人接受变更通知、容量报警、活性报警、拒绝报警、任务超时报警等通知,方便项目组同事企业微信群实时监控线程池状态,动态调整线程参数。
接手开始上手,一看网上教程和demo很多啊,心中窃喜,一顿ctrl+c+v大发,却发现告警不通知,配置线程池不生效,数着承诺的交付时间,开始发慌;几经周折,才定,斯文于记。
1、引入POM文件
spring-cloud场景下的nacos应用接入用此依赖:
<dependency> <groupId>cn.dynamictp</groupId> <artifactId>dynamic-tp-spring-cloud-starter-nacos</artifactId> <version>1.0.8</version> </dependency>
非spring-cloud 场景下的nacos应用接入用此依赖:
<dependency> <groupId>cn.dynamictp</groupId> <artifactId>dynamic-tp-spring-boot-starter-nacos</artifactId> <version>1.0.8</version> </dependency>
2、启动类加 @EnableDynamicTp 注解
3、配置中心配置线程池yml实例
spring: dynamic: tp: enabled: true enabledBanner: true # 是否开启banner打印,默认true enabledCollect: true # 是否开启监控指标采集,默认false collectorTypes: micrometer,logging # 监控数据采集器类型(logging | micrometer | internal_logging),默认micrometer logPath: /home/logs # 监控日志数据路径,默认 ${user.home}/logs,采集类型非logging不用配置 monitorInterval: 5 # 监控时间间隔(报警判断、指标采集),默认5s nacos: # nacos配置,不配置有默认值(规则appname-dev.yml这样),cloud应用不需要配置 dataId: dynamic-tp-demo-dev.yml group: DEFAULT_GROUP apollo: # apollo配置,不配置默认拿apollo配置第一个namespace namespace: dynamic-tp-demo-dev.yml configType: yml # 配置文件类型,非cloud nacos 和 apollo需配置,其他不用配 platforms: # 通知报警平台配置 - platform: wechat urlKey: 3a700-127-4bd-a798-c53d8b69c # 替换 receivers: test1,test2 # 接受人企微名称 - platform: ding urlKey: f80dad441fcd655438f4a08dcd6a # 替换 secret: SECb5441fa6f375d5b9d21 # 替换,非sign模式可以没有此值 receivers: 18888888888 # 钉钉账号手机号 - platform: lark urlKey: 0d944ae7-b24a-40 # 替换 receivers: test1,test2 # 接受人飞书名称/openid tomcatTp: # tomcat webserver线程池配置 corePoolSize: 100 maximumPoolSize: 200 keepAliveTime: 60 jettyTp: # jetty weberver线程池配置 corePoolSize: 100 maximumPoolSize: 200 undertowTp: # undertow webserver线程池配置 corePoolSize: 100 maximumPoolSize: 200 keepAliveTime: 60 hystrixTp: # hystrix 线程池配置 - threadPoolName: hystrix1 corePoolSize: 100 maximumPoolSize: 200 keepAliveTime: 60 dubboTp: # dubbo 线程池配置 - threadPoolName: dubboTp#20880 # 名称规则:dubboTp + "#" + 协议端口 threadPoolAliasName: 测试线程池 # dubbo线程池 corePoolSize: 100 maximumPoolSize: 200 keepAliveTime: 60 notifyItems: # 报警项,不配置自动会按默认值配置(变更通知、容量报警、活性报警) - type: capacity # 报警项类型,查看源码 NotifyTypeEnum枚举类 enabled: true threshold: 80 # 报警阈值 platforms: [ding,wechat] # 可选配置,不配置默认拿上层platforms配置 interval: 120 # 报警间隔(单位:s) rocketMqTp: # rocketmq 线程池配置 - threadPoolName: group1#topic1 # 名称规则:group + "#" + topic corePoolSize: 200 maximumPoolSize: 200 keepAliveTime: 60 executors: # 动态线程池配置 - threadPoolName: dtpExecutor1 threadPoolAliasName: 测试线程池 # 线程池别名 executorType: common # 线程池类型common、eager:适用于io密集型 corePoolSize: 6 maximumPoolSize: 8 queueCapacity: 200 queueType: VariableLinkedBlockingQueue # 任务队列,查看源码QueueTypeEnum枚举类 rejectedHandlerType: CallerRunsPolicy # 拒绝策略,查看RejectedTypeEnum枚举类 keepAliveTime: 50 allowCoreThreadTimeOut: false # 是否允许核心线程池超时 threadNamePrefix: test # 线程名前缀 waitForTasksToCompleteOnShutdown: false # 参考spring线程池设计,优雅关闭线程池 awaitTerminationSeconds: 5 # 单位(s) preStartAllCoreThreads: false # 是否预热所有核心线程,默认false runTimeout: 200 # 任务执行超时阈值,目前只做告警用,单位(ms) queueTimeout: 100 # 任务在队列等待超时阈值,目前只做告警用,单位(ms) taskWrapperNames: ["ttl"] # 任务包装器名称,集成TaskWrapper接口 notifyItems: # 报警项,不配置自动会按默认值配置(变更通知、容量报警、活性报警、拒绝报警、任务超时报警) - type: capacity # 报警项类型,查看源码 NotifyTypeEnum枚举类 enabled: true threshold: 80 # 报警阈值 platforms: [ding,wechat] # 可选配置,不配置默认拿上层platforms配置的所以平台 interval: 120 # 报警间隔(单位:s) - type: change enabled: true - type: liveness enabled: true threshold: 80 - type: reject enabled: true threshold: 1 - type: run_timeout enabled: true threshold: 1 - type: queue_timeout enabled: true threshold: 1
服务启动时会根据配置中心的配置[dtpExecutor1]动态注册到Spring容器中。
4、配置线程池使用
@Resource或@Autowired进行依赖注入,或通过 DtpRegistry.getDtpExecutor("name")获取。
@Resource private ThreadPoolExecutor dtpExecutor1;
DtpExecutor dtpExecutor = DtpRegistry.getDtpExecutor("dtpExecutor1"); dtpExecutor.execute(() -> System.out.println("test"));
以上4步,顺利话可以接入使用了:
| __ \ (_) |__ __| | | | |_ _ _ __ __ _ _ __ ___ _ ___| |_ __ | | | | | | | '_ \ / _` | '_ ` _ | |/ __| | '_ \ | |__| | |_| | | | | (_| | | | | | | | (__| | |_) | |_____/ __, |_| |_|__,_|_| |_| |_|_|___|_| .__/ __/ | | | |___/ |_| :: Dynamic Thread Pool :: DynamicTp register dtpExecutor, source: beanPostProcessor, executor: DtpMainPropWrapper(dtpName=dynamic-tp-test-1, corePoolSize=6, maxPoolSize=8, keepAliveTime=50, queueType=VariableLinkedBlockingQueue, queueCapacity=200, rejectType=RejectedCountableCallerRunsPolicy, allowCoreThreadTimeOut=false) DtpRegistry initialization end, remote dtpExecutors: [dtpExecutor1, dtpExecutor2], local dtpExecutors: [ioIntensiveExecutor], local commonExecutors: [commonExecutor]
启动日志出现, remote dtpExecutors便是配置注册的线程池了,那么恭喜。
当然我们也可以在程序中定义线程池代替配置文件,但是官方不推荐,官方推荐的配置文件配置。普通 JUC线程池想要被监控,可以@Bean定义时加 @DynamicTp 注解。
* 1、 (ThreadPoolExecutor) Executors.newFixedThreadPool(1)加@DynamicTp("commonExecutor") * 2、ThreadPoolCreator.createDynamicFast("dynamic-tp-test-1"); * 3、ThreadPoolBuilder.newBuilder()
二、避坑指南
1、yaml配置单独文件,不同的nacos配置可能会有差异,以nacos 2.0.2为例: 配置文件添加后缀.yml或者.yaml
2、阻塞队列只有VariableLinkedBlockingQueue类型可以修改capacity,该类型功能和 LinkedBlockingQueue相似,只是capacity不是final类型,可以修改。
3、配置企微机器人地址KEY
platform: wechat urlKey: 3a700-127-4bd-a798-c53d8b69c # 机器人地址后的key receivers: test1 # 指定接收人企微名称,默认@所有人
机器人配置参考企微webhook
4、重要类DtpBeanDefinitionRegistrar配置转换
加载全部内容