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