我們一起聊聊動態線程池框架 DynamicTP
前言
在微服務架構中,線程池作為服務器的核心組件,對于系統的性能和穩定性起著至關重要的作用。傳統的線程池配置通常是靜態的,這意味著一旦設定,其核心參數(如核心線程數、最大線程數、隊列大小等)很難在運行時根據業務的動態變化進行調整。這可能導致在高負載時線程池資源緊張,而在低負載時又會造成資源的浪費。為了解決這些問題,DynamicTP 框架應運而生,它為我們提供了強大的動態線程池管理能力,同時還具備完善的監控和告警功能,能夠極大地提升系統的性能和穩定性。
DynamicTP 是一個開源的動態線程池框架,它允許開發人員在運行時動態調整線程池的各項參數,并且可以對線程池的運行狀態進行實時監控和告警。它基于 Java 的內置線程池機制,如 ThreadPoolExecutor,并在此基礎上進行擴展和優化,為開發者提供了更加靈活和智能的線程池管理方案。
快速開始
官網:https://dynamictp.cn/guide/introduction/background.html
無配置中心應用接入
SpringBoot1x、2x 用此依賴
<dependency>
<groupId>org.dromara.dynamictp</groupId>
<artifactId>dynamic-tp-spring-boot-starter-common</artifactId>
<version>1.1.9.1</version>
</dependency>
線程池配置文件
下述配置項的值都是隨便填寫的,請不要直接使用該值,根據自己項目做調整
spring:
dynamic:
tp:
enabled: true # 是否啟用 dynamictp,默認true
enabledCollect: true # 是否開啟監控指標采集,默認true
collectorTypes: micrometer,logging # 監控數據采集器類型(logging | micrometer | internal_logging | JMX),默認micrometer
logPath: /home/logs/dynamictp/user-center/ # 監控日志數據路徑,默認 ${user.home}/logs,采集類型非logging不用配置
monitorInterval: 5 # 監控時間間隔(報警檢測、指標采集),默認5s
platforms: # 通知報警平臺配置
- platform: wechat
platformId: 1 # 平臺id,自定義
urlKey: 3a700-127-4bd-a798-c53d8b69c # webhook 中的 key
receivers: test1,test2 # 接受人企微賬號
- platform: ding
platformId: 2 # 平臺id,自定義
urlKey: f80dad441fcd655438f4a08dcd6a # webhook 中的 access_token
secret: SECb5441fa6f375d5b9d21 # 安全設置在驗簽模式下才的秘鑰,非驗簽模式沒有此值
receivers: 18888888888 # 釘釘賬號手機號
- platform: lark
platformId: 3
urlKey: 0d944ae7-b24a-40 # webhook 中的 token
secret: 3a750012874bdac5c3d8b69c # 安全設置在簽名校驗模式下才的秘鑰,非驗簽模式沒有此值
receivers: test1,test2 # 接受人username / openid
- platform: email
platformId: 4
receivers: 123456@qq.com,789789@qq.com # 收件人郵箱,多個用逗號隔開
executors: # 動態線程池配置,都有默認值,采用默認值的可以不配置該項,減少配置量
- threadPoolName: dtpExecutor1 # 線程池名稱,必填
threadPoolAliasName: 測試線程池 # 線程池別名,可選
executorType: common # 線程池類型 common、eager、ordered、scheduled、priority,默認 common
corePoolSize: 6 # 核心線程數,默認1
maximumPoolSize: 8 # 最大線程數,默認cpu核數
queueCapacity: 2000 # 隊列容量,默認1024
queueType: VariableLinkedBlockingQueue # 任務隊列,查看源碼QueueTypeEnum枚舉類,默認VariableLinkedBlockingQueue
rejectedHandlerType: CallerRunsPolicy # 拒絕策略,查看RejectedTypeEnum枚舉類,默認AbortPolicy
keepAliveTime: 60 # 空閑線程等待超時時間,默認60
threadNamePrefix: test # 線程名前綴,默認dtp
allowCoreThreadTimeOut: false # 是否允許核心線程池超時,默認false
waitForTasksToCompleteOnShutdown: true # 參考spring線程池設計,優雅關閉線程池,默認true
awaitTerminationSeconds: 5 # 優雅關閉線程池時,阻塞等待線程池中任務執行時間,默認3,單位(s)
preStartAllCoreThreads: false # 是否預熱所有核心線程,默認false
runTimeout: 200 # 任務執行超時閾值,單位(ms),默認0(不統計)
queueTimeout: 100 # 任務在隊列等待超時閾值,單位(ms),默認0(不統計)
taskWrapperNames: ["ttl", "mdc"] # 任務包裝器名稱,繼承TaskWrapper接口
notifyEnabled: true # 是否開啟報警,默認true
platformIds: [1,2] # 報警平臺id,不配置默認拿上層platforms配置的所有平臺
notifyItems: # 報警項,不配置自動會按默認值(查看源碼NotifyItem類)配置(變更通知、容量報警、活性報警、拒絕報警、任務超時報警)
- type: change
enabled: true
- type: capacity # 隊列容量使用率,報警項類型,查看源碼 NotifyTypeEnum枚舉類
enabled: true
threshold: 80 # 報警閾值,默認70,意思是隊列使用率達到70%告警
platformIds: [2] # 可選配置,本配置優先級 > 所屬線程池platformIds > 全局配置platforms
interval: 120 # 報警間隔(單位:s),默認120
- type: liveness # 線程池活性
enabled: true
threshold: 80 # 報警閾值,默認 70,意思是活性達到70%告警
- type: reject # 觸發任務拒絕告警
enabled: true
threshold: 100 # 默認閾值10
- type: run_timeout # 任務執行超時告警
enabled: true
threshold: 100 # 默認閾值10
- type: queue_timeout # 任務排隊超時告警
enabled: true
threshold: 100 # 默認閾值10
代碼引用
依賴注入方式使用,優先推薦依賴注入方式,不能使用依賴注入的場景可以使用方式2
@Resource
private ThreadPoolExecutor dtpExecutor1;
public void exec() {
dtpExecutor1.execute(() -> System.out.println("test"));
}
從 DtpRegistry 注冊器獲取(接口場景可用)
public static void main(String[] args) {
DtpExecutor dtpExecutor = DtpRegistry.getDtpExecutor("dtpExecutor1");
dtpExecutor.execute(() -> System.out.println("test"));
}
最后
DynamicTP 框架為微服務架構中的線程池管理提供了強大的支持,通過其動態調整參數、監控和告警功能,開發者可以更好地應對復雜多變的業務場景,提升系統的性能和穩定性。在實際開發中,合理使用 DynamicTP 可以有效避免線程池資源的浪費和性能瓶頸,是構建高性能微服務的有力工具。 請注意,在使用 DynamicTP 時,需要根據實際業務需求和系統負載,合理設置線程池的初始參數和告警閾值,以充分發揮其優勢。