美文网首页
业务实战场景(十七)动态线程池技术方案

业务实战场景(十七)动态线程池技术方案

作者: 后来丶_a24d | 来源:发表于2023-01-07 11:19 被阅读0次

目录

  • 系列总目录
  • 背景
  • 简单实现
  • 美团开源方案DynamicTp
    • 架构
      • 监控模块
      • 通知告警模块
    • 特性
  • 参考文章

系列总目录


背景

  • 对于线程池核心参数的配置很大程度上依靠经验。然而,由于系统运行过程中存在的不确定性,我们很难一劳永逸地规划一个合理的线程池参数。在对线程池配置参数进行调整时,一般需要对服务进行重启,这样修改的成本就会偏高。一种解决办法就是,将线程池的配置放到平台侧,运行开发同学根据系统运行情况对核心参数进行动态配置
  • 这里有两种实现方案,一种是用配置中心比如Nacos,Apollo监听配置的变化更新线程池参数查看最合适的。另一种是用美团开源的线程池框架DynamicTp

简单实现

  • 根据配置中心变更配置动态 + 线程池setCorePoolSize底层支持,便可实现动态变更。setCorePoolSize根据需要增加或者减少核心线程数量,动态增加或者减少线程队列对应的Worker数量,核心代码
@Configuration
public class DynamicThreadPool implements InitializingBean {
   @Override
    public void afterPropertiesSet() throws Exception {
        // 按照配置中心初始化线程池,这里简单举例nacos
        threadPoolExecutor = new ThreadPoolExecutor(Integer.parseInt(coreSize), Integer.parseInt(maxSize), 10L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(10),
                new ThreadFactoryBuilder().setNameFormat("c_t_%d").build(),
                new RejectedExecutionHandler() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                        System.out.println("rejected!");
                    }
                });
 
        // 根据配置变更监听从而改变线程池参数,这里举例nacos,apollo思路也是一样只是api不同
        nacosConfigManager.getConfigService().addListener("order-service-dev.yml", nacosConfigProperties.getGroup(),
                new Listener() {
                    @Override
                    public Executor getExecutor() {
                        return null;
                    }
 
                    @Override
                    public void receiveConfigInfo(String configInfo) {
                        //配置变更,修改线程池配置
                        System.out.println(configInfo);
                        changeThreadPoolConfig(Integer.parseInt(coreSize);
                    }
                });
    }
   /**
     * 修改线程池核心参数
     *
     * @param coreSize
     * @param maxSize
     */
    private void changeThreadPoolConfig(int coreSize) {
        threadPoolExecutor.setCorePoolSize(coreSize);
    }
}

美团开源方案DynamicTp

架构

  • 主要分为几个模块
    1.配置变更监听模块
    2.服务内部线程池管理模块
    3.三方组件线程池管理模块
    4.监控模块
    5.通知告警模块


    架构.png
监控模块
  • 实现监控指标采集以及输出,默认提供以下三种方式,也可通过内部提供的 SPI 接口扩展其他实现
  1. 默认实现 JsonLog 输出到磁盘,可以自己采集解析日志,存储展示,比如Flume采集日志到Kafka,然后Kafka分析
  2. MicroMeter采集,引入 MicroMeter 相关依赖,暴露相关端点,采集指标数据,结合 Grafana 做监控大盘,默认这种模式
  3. 暴露自定义 Endpoint 端点(dynamic-tp),可通过 http 方式实时访
  • 一般采用第二点prometheus+grafana监控展示和采集
通知告警模块
  • 对接办公平台,实现通知告警功能,已支持钉钉、企微、飞书、邮件,可通过内部提供的 SPI 接口扩展其他实现
  • 服务启动后会开启一个定时监控任务,每隔一定时间(可配置)去计算线程池的活跃度,达到配置的 threshold 阈值后会触发一次告警

特性

  • 相对自己实现,DynamicTp增加了很多特性
  1. 代码零侵入
  2. 通知告警
  3. 运行监控
  4. 任务增强, 支持上下文传递
  5. 多配置中心支持,Nacos、Apollo、Zookeeper、Consul、Etcd
  6. 中间件线程池管理
  • 通知告警模块


    告警1.png
    告警2.png
  • 监控


    监控.png
  • 暴露 EndPoint 端点(dynamic-tp),可以通过 http 方式请求
[
    {
        "dtp_name": "remoting-call",
        "core_pool_size": 6,
        "maximum_pool_size": 12,
        "queue_type": "SynchronousQueue",
        "queue_capacity": 0,
        "queue_size": 0,
        "fair": false,
        "queue_remaining_capacity": 0,
        "active_count": 0,
        "task_count": 21760,
        "completed_task_count": 21760,
        "largest_pool_size": 12,
        "pool_size": 6,
        "wait_task_count": 0,
        "reject_count": 124662,
        "reject_handler_name": "CallerRunsPolicy"
    }
]

参考文章

相关文章

  • 有了 CompletableFuture,使得异步编程没有那么难

    本文导读: 业务需求场景介绍 技术设计方案思考 Future 设计模式实战 CompletableFuture 模...

  • 第六章、服务器业务逻辑处理框架

    6.1、业务处理逻辑之多线程、线程池实战//(3.1)为什么引入线程池//我们完全不推荐用单线程的方式解决逻辑业务...

  • 业务场景实战(七)阿里TTL线程池

    思维导图 思维导图.png 系列总目录 业务场景实战汇总[https://www.jianshu.com/p/8e...

  • Java线程池 ThreadPoolExecutor 业务线程池

    1.什么是业务线程池? 在业务开发中,用来处理业务的线程池。 2.为什么需要业务线程池? 大多数同学都是做业务开发...

  • 源码|从串行线程封闭到对象池、线程池

    今天讲一个牛逼而实用的概念,串行线程封闭。对象池是串行线程封闭的典型应用场景;线程池糅合了对象池技术,但核心实现不...

  • Android 架构设计

    架构是针对某类业务场景通用的解决方案,是对具体业务场景的抽象描述。架构设计又分为业务架构和技术架构。技术架构依赖于...

  • Servlet3之NIO线程池隔离

    线程隔离主要是针对业务中不同业务场景,按照权重区分使用不同的线程池,以达到某一个业务出现问题,不会将故障扩散到其他...

  • 并发编程工具(二)CyclicBarrier 循环屏障

    爱称:线程疯狂堵塞器简介:简单,好用,好上手,就是能用的业务场景不多ps:会堵塞我线程池挺多线程的 要是任务确实很...

  • 线程池

    1.为什么要使用线程池?2.线程池的基本原理是什么?3.怎么学习线程池?线程池使用了池化技术。池化技术用于我们常见...

  • 八、线程池剖析

    一、前置问题 线程的状态转换 为什么要使用线程池 线程池的继承体系 线程池使用的场景 线程数的设置规则 线程池的状...

网友评论

      本文标题:业务实战场景(十七)动态线程池技术方案

      本文链接:https://www.haomeiwen.com/subject/psgecdtx.html