天天看點

springcloud配置中心nacos動态線程池Dynamic-tp配置接入實戰

作者:馬士兵教育CTO
springcloud配置中心nacos動态線程池Dynamic-tp配置接入實戰

最近業務上需要把項目組幾個微服務接入動态線程池架構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 注解

springcloud配置中心nacos動态線程池Dynamic-tp配置接入實戰

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

springcloud配置中心nacos動态線程池Dynamic-tp配置接入實戰

2、阻塞隊列隻有VariableLinkedBlockingQueue類型可以修改capacity,該類型功能和 LinkedBlockingQueue相似,隻是capacity不是final類型,可以修改。

3、配置企微機器人位址KEY

platform: wechat
urlKey: 3a700-127-4bd-a798-c53d8b69c     # 機器人位址後的key
receivers: test1                         # 指定接收人企微名稱,預設@所有人
                 

機器人配置參考企微webhook

4、重要類DtpBeanDefinitionRegistrar配置轉換

springcloud配置中心nacos動态線程池Dynamic-tp配置接入實戰