李锋镝的博客

  • 首页
  • 时间轴
  • 说说
  • 每日心情
  • Now
  • 系列文章
  • 论坛
  • 左邻右舍
    • 左邻右舍
    • 博友圈
  • 留言
    • 留言
    • 走心评论
  • 关于
    • 关于本站
    • 网站地图
    • 网站统计
    • 另一个网站
    • 我的导航站
    • 赞助
  • 🚇开往
Destiny
自是人生长恨水长东
  1. 首页
  2. 原创
  3. 正文

动态线程池框架DynamicTp使用以及架构设计

2025年4月29日 约 1,807 字7 分钟 128 0 0
本文最后更新于 2025年4月29日,距今已 501 天,其中的信息可能已经发生变化,请注意甄别。

DynamicTp 是什么

DynamicTp 是一个基于 Java 的动态线程池框架,特性如下:

  • 代码零侵入:我们改变了线程池以往的使用姿势,所有配置均放在配置中心,服务启动时会从配置中心拉取配置生成线程池对象放到 Spring 容器中,使用时直接从 Spring 容器中获取,对业务代码零侵入

  • 轻量简单:使用起来极其简单,引入相应依赖,接入只需简单 4 步就可完成,顺利 3 分钟搞定,相当丝滑

  • 通知告警:提供多种通知告警维度(配置变更通知、活性报警、队列容量阈值报警、拒绝触发报警、任务执行或等待超时报警),触发配置阈值实时推送告警信息,已支持企微、钉钉、飞书、邮件、云之家报警,同时提供 SPI 接口可自定义扩展实现

  • 运行监控:定时采集线程池指标数据(20 多种指标,包含线程池维度、队列维度、任务维度、tps、tpxx 等),支持通过 MicroMeter、JsonLog、JMX 三种方式定时获取,也可以通过 SpringBoot Endpoint 端点实时获取最新指标数据,同时提供 SPI 接口可自定义扩展实现

  • 任务增强:提供任务包装功能(比 Spring 线程池任务包装更强大),实现 TaskWrapper 接口即可,如 MdcTaskWrapper、TtlTaskWrapper、SwTraceTaskWrapper、OpenTelemetryWrapper,可以支持线程池上下文信息传递

  • 多配置中心支持:支持多种主流配置中心,包括 Nacos、Apollo、Zookeeper、Consul、Etcd、Polaris、ServiceComb,同时也提供 SPI 接口可自定义扩展实现

  • 中间件线程池管理:集成管理常用第三方组件的线程池,已集成 Tomcat、Jetty、Undertow、Dubbo、RocketMq、Hystrix、Grpc、Motan、Okhttp3、Brpc、Tars、SofaRpc、RabbitMq、Liteflow 等组件的线程池管理(动态调参、监控、报警)

  • 多模式:提供了增强线程池 DtpExecutor,IO 密集型场景使用的线程池 EagerDtpExecutor,调度线程池 ScheduledDtpExecutor,有序线程池 OrderedDtpExecutor,可以根据业务场景选择合适的线程池

  • 兼容性:JUC 普通线程池和 Spring 中的 ThreadPoolTaskExecutor 也可以被框架管理,只需@Bean 定义时加 @DynamicTp 注解即可

  • 可靠性:依靠 Spring 生命周期管理,可以做到优雅关闭线程池,在 Spring 容器关闭前尽可能多的处理队列中的任务

  • 高可扩展:框架核心功能都提供 SPI 接口供用户自定义个性化实现(配置中心、配置文件解析、通知告警、监控数据采集、任务包装、拒绝策略等等)

  • 线上大规模应用:参考美团线程池实践,美团内部已经有该理论成熟的应用经验

示例代码

以下是一个使用 DynamicTp 实现动态调整线程池线程数量的完整实例代码,本示例基于 Spring Boot 框架,使用 Nacos 作为配置中心。

1. 添加依赖

在 pom.xml 中添加 DynamicTp 和 Nacos 相关依赖:

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- DynamicTp -->
    <dependency>
        <groupId>cn.dynamic-tp</groupId>
        <artifactId>dynamic-tp-spring-boot-starter</artifactId>
        <version>1.1.4</version>
    </dependency>
    <!-- Nacos Config -->
    <dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-client</artifactId>
        <version>2.2.0</version>
    </dependency>
</dependencies>

2. 配置 Nacos

在 application.yml 中配置 Nacos 信息:

spring:
  application:
    name: dynamic-tp-demo
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml

3. 配置线程池

在 Nacos 配置中心创建一个 dynamic-tp-demo.yaml 文件,添加线程池配置:

spring:
  dynamic:
    tp:
      enabled: true
      executors:
        - threadPoolName: myDynamicTp
          corePoolSize: 5
          maxPoolSize: 10
          queueCapacity: 200
          keepAliveTime: 60
          timeUnit: SECONDS

4. 创建线程池 Bean

在 Spring Boot 项目中创建线程池 Bean:

import com.dtp.core.annotation.DynamicTp;
import com.dtp.core.support.ThreadPoolBuilder;
import com.dtp.core.thread.DtpExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ExecutorService;

@Configuration
public class ThreadPoolConfig {

    @Bean
    @DynamicTp
    public ExecutorService myDynamicTp() {
        return ThreadPoolBuilder.newBuilder()
               .threadPoolName("myDynamicTp")
               .buildDynamic();
    }
}

5. 创建测试服务

创建一个服务类,使用线程池执行任务:

import org.springframework.stereotype.Service;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

@Service
public class TaskService {

    private final ExecutorService executorService;

    public TaskService(ExecutorService myDynamicTp) {
        this.executorService = myDynamicTp;
    }

    public void submitTask() {
        executorService.submit(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
                System.out.println("Task executed by thread: " + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
    }
}

6. 创建控制器

创建一个控制器来触发任务提交:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TaskController {

    @Autowired
    private TaskService taskService;

    @GetMapping("/submitTask")
    public String submitTask() {
        taskService.submitTask();
        return "Task submitted.";
    }
}

7. 运行项目并测试

启动 Spring Boot 项目,访问 http://localhost:8080/submitTask 来提交任务。

8. 动态调整线程池参数

在 Nacos 配置中心修改 dynamic-tp-demo.yaml 文件中的线程池参数,例如将 corePoolSize 改为 8,maxPoolSize 改为 15,保存配置后,DynamicTp 会自动监听配置变更并动态调整线程池的线程数量。

架构设计

框架功能大体可以分为以下几个模块

  1. 配置变更监听模块

  2. 线程池管理模块

  3. 监控模块

  4. 通知告警模块

  5. 三方组件线程池管理模块

更新线程池逻辑

具体逻辑在 DtpRegistry 类中的 doRefreshPoolSize 方法,其功能是根据新的线程池属性配置(DtpExecutorProps)来更新线程池的核心线程数(corePoolSize)和最大线程数(maximumPoolSize)。

代码如下:

    private static void doRefreshPoolSize(ExecutorAdapter<?> executor, DtpExecutorProps props) {
        if (props.getMaximumPoolSize() < executor.getMaximumPoolSize()) {
            if (!Objects.equals(executor.getCorePoolSize(), props.getCorePoolSize())) {
                executor.setCorePoolSize(props.getCorePoolSize());
            }
            if (!Objects.equals(executor.getMaximumPoolSize(), props.getMaximumPoolSize())) {
                executor.setMaximumPoolSize(props.getMaximumPoolSize());
            }
            return;
        }
        if (!Objects.equals(executor.getMaximumPoolSize(), props.getMaximumPoolSize())) {
            executor.setMaximumPoolSize(props.getMaximumPoolSize());
        }
        if (!Objects.equals(executor.getCorePoolSize(), props.getCorePoolSize())) {
            executor.setCorePoolSize(props.getCorePoolSize());
        }
    }
  1. 方法参数:

    • ExecutorAdapter<?> executor:表示要更新配置的线程池执行器适配器,通过这个适配器可以调用线程池的各种设置方法,如设置核心线程数和最大线程数。
    • DtpExecutorProps props:包含了新的线程池属性配置,其中包括新的核心线程数和最大线程数等信息。
  2. 主要逻辑:

    • 首先判断新的最大线程数(props.getMaximumPoolSize())是否小于当前线程池的最大线程数(executor.getMaximumPoolSize()):
      • 如果新的最大线程数小于当前最大线程数,说明需要缩小线程池规模。此时先检查核心线程数是否需要更新,即比较当前核心线程数(executor.getCorePoolSize())和新的核心线程数(props.getCorePoolSize())是否相等。如果不相等,则调用 executor.setCorePoolSize(props.getCorePoolSize()) 方法将核心线程数更新为新的值。
      • 接着检查最大线程数是否需要更新,比较当前最大线程数和新的最大线程数是否相等。如果不相等,则调用 executor.setMaximumPoolSize(props.getMaximumPoolSize()) 方法将最大线程数更新为新的值。
      • 完成上述操作后,通过 return 语句结束方法,不再执行后续逻辑。
    • 如果新的最大线程数不小于当前最大线程数,说明不需要缩小线程池规模,或者是要扩大线程池规模。此时先检查最大线程数是否需要更新,即比较当前最大线程数和新的最大线程数是否相等。如果不相等,则调用 executor.setMaximumPoolSize(props.getMaximumPoolSize()) 方法将最大线程数更新为新的值。
    • 最后检查核心线程数是否需要更新,比较当前核心线程数和新的核心线程数是否相等。如果不相等,则调用 executor.setCorePoolSize(props.getCorePoolSize()) 方法将核心线程数更新为新的值。

参考链接

1
  1. 1美团线程池实践tech.meituan.com
除非注明,否则均为李锋镝的博客原创文章,转载必须以链接形式标明本文链接

本文链接:https://www.lifengdi.com/article/4383

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
分享到

动态线程池框架DynamicTp使用以及架构设计

也可使用浏览器菜单中的「分享」功能

微信扫一扫分享

标签: DynamicTp JAVA 动态线程池 多线程 线程池
最后更新:2025年4月29日

岁月同一天 9 月 13 日

回望过去的今天,你在写什么

  • 日常
    4 年前 2022年9月13日
    这个中秋节感觉过的好累啊

    去了趟丈母娘家,每天吃了睡睡了吃,还是感觉困的不行…… 天呐~ 一天天,迷迷瞪瞪的~ :douyin.12: 

相关文章
  • Java设计模式:状态模式2025年5月22日
  • Java中ArrayList为什么比LinkedList查询速度快?2020年5月16日
  • Spring中@NotNull、@NotBlank、@NotEmpty的区别2019年7月2日
  • Java整数运算2022年7月15日
  • SpringBoot整合Elasticsearch游标查询(scroll)2020年10月16日

李锋镝

既然选择了远方,便只顾风雨兼程。

打赏 点赞
< 上一篇
下一篇 >
1234567891112131415161718192021222324252627282930313233343536373839404142434446474849505152535455575859606162636465666769727476777879808182858687909293949596979899
取消回复

文章评论

还没有评论,快来抢沙发吧~

看别人买瓶红茶都送给女朋友,不由得想起高中时代。高三那年夏天,有一次女神口渴,要她闺蜜给她带瓶水,我赶快把我刚买的红茶递过去。女神很意外,但还是接了过去。我心里正得意地笑呢,女神递回来一个瓶盖说:“还你一瓶水,不欠你了哈!”唉,这“再来一瓶”来的真不是时候!

听点儿音乐吧 朋友~
文章目录
最新 热点 随机
最新 热点 随机
关于主题加载速度优化的一点儿小演进 市场主流AI编程大模型横向深度分析(2026-09-11) 一款节省token的利器:RTK(Rust Token Killer) RAG太难学?LLM Wiki了解一下 推荐一个SVG 矢量小图标免费下载网站 关于使用AI的一些思考
给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能WordPress缓存插件WP Fastest Cache、WP Rocket 、FlyingPress对比关于使用AI的一些思考Kratos+ v1.1.16版本更新说明AI时代,个人技术博客的出路在哪里?推荐一个SVG 矢量小图标免费下载网站
妹妹的画【2019.07.03】 别再背线程池的七大参数了,现在面试官都这么问 属性名称闹的一场乌龙事件 GPT-5.1深度测评:从智能升级到情感共鸣,AI交互的下一个里程碑 动态线程池框架DynamicTp使用以及架构设计 Spring中的Aware接口
最近评论
blank
皮皮社长 发布于 16 小时前(09月12日) 我主题里的svg图标也全都下载到了本地, :19: 方便日后替换。
blank
Liudon 发布于 19 小时前(09月12日) 我是GPT出方案和审核,DeepSeek干活 :8:
blank
李锋镝 发布于 21 小时前(09月12日) 其实没必要的话,免费薅羊毛的就够用了,豆包也不是不行~
blank
obaby 发布于 21 小时前(09月12日) 我还是有免费的用免费,没免费的捡性价比高的。
blank
李锋镝 发布于 22 小时前(09月12日) 那个总感觉和淘宝类似,加入购物车、结算、然后再使用
标签聚合
AI WordPress Spring IDEA MySQL SQL 数据库 日常 MQ 分布式 多线程 Claude 架构 SpringBoot JVM AI编程 ElasticSearch Redis JAVA K8s
友情链接
  • 林羽凡
  • Mr.Sun的博客
  • 临窗旋墨
  • 志文工作室
  • 韩小韩博客
  • 懋和道人
  • 搬砖日记
  • Serendipity
  • 皮皮社
  • 瓦匠个人小站
  • 韩情脉脉
  • Honesty
  • 知向前端
  • sssr7844的博客
  • 彬红茶日记
  • 九仞之行
  • 老张博客
  • 蜗牛工作室
  • 若梦博客
  • 哥斯拉

COPYRIGHT © 2016-2026 lifengdi.com. ALL RIGHTS RESERVED.

Domain age badge for lifengdi.com

Theme Kratos-plus By Dylan Li

津ICP备2024022503号-3

京公网安备11011502039375号