首页 > 其他分享 >美团动态线程池

美团动态线程池

时间:2025-01-15 16:58:13浏览次数:3  
标签:报警 监控 实现 美团 配置 线程 模块 动态

使用线程池 ThreadPoolExecutor 过程中你是否有以下痛点呢?

  1. 代码中创建了一个 ThreadPoolExecutor,但是不知道那几个核心参数设置多少比较合适

  2. 凭经验设置参数值,上线后发现需要调整,改代码重启服务,非常麻烦

  3. 线程池相对开发人员来说是个黑盒,运行情况不能及时感知到,直到出现问题

如果你有以上痛点,动态可监控线程池(DynamicTp)或许能帮助到你。

背景

如果看过 ThreadPoolExecutor 的源码,大概可以知道它对核心参数基本都有提供 set/get 方法以及一些扩展方法,可以在运行时动态修改、获取相应的值。

现在大多数的互联网项目其实都会微服务化部署,有一套自己的服务治理体系,微服务组件中的分布式配置中心扮演的就是动态修改配置, 实时生效的角色。那么我们是否可以结合配置中心来做运行时线程池参数的动态调整呢?

答案是肯定的,而且配置中心相对都是高可用的, 使用它也不用过于担心配置推送出现问题这类事儿,而且也能减少研发动态线程池组件的难度和工作量。

综上,可以总结出以下的背景
  • 广泛性: 在 Java 开发中,想要提高系统性能,线程池已经是一个 90%以上的人都会选择使用的基础工具

  • 不确定性: 项目中可能会创建很多线程池,既有 IO 密集型的,也有 CPU 密集型的,但线程池的参数并不好确定;需要有套机制在运行过程中动态去调整参数

  • 无感知性: 线程池运行过程中的各项指标一般感知不到;需要有套监控报警机制在事前、事中就能让开发人员感知到线程池的运行状况,及时处理

  • 高可用性: 配置变更需要及时推送到客户端;需要有高可用的配置管理推送服务,配置中心是现在大多数互联网系统都会使用的组件,与之结合可以大幅度减少开发量及接入难度

简介

基于以上背景分析,我们对线程池 ThreadPoolExecutor 做一些扩展增强,主要实现以下目标

  1. 实现对运行中线程池参数的动态修改,实时生效

  2. 实时监控线程池的运行状态,触发设置的报警策略时报警,报警信息推送办公平台

  3. 定时采集线程池指标数据,配合像 grafana 这种可视化监控平台做大盘监控

经过多个版本的迭代,目前最新版本 v1.0.9 具有以下特性
  • 代码零侵入:所有配置都放在配置中心,对业务代码零侵入

  • 轻量简单:基于 SpringBoot 实现,引入 starter,接入只需简单 4 步就可完成,顺利 3 分钟搞定

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

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

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

  • 监控:定时采集线程池指标数据,支持通过 MicroMeterJsonLog 日志输出、Endpoint 三种方式,可通过 SPI 接口自定义扩展实现

  • 任务增强:提供任务包装功能,实现 TaskWrapper 接口即可,如 MdcTaskWrapperTtlTaskWrapperSwTraceTaskWrapper,可以支持线程池上下文信息传递

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

  • 可靠性:框架提供的线程池实现 Spring 生命周期方法,可以在 Spring 容器关闭前尽可能多的处理队列中的任务

  • 多模式:参考 Tomcat 线程池提供了 IO 密集型场景使用的 EagerDtpExecutor 线程池

  • 支持多配置中心:基于主流配置中心实现线程池参数动态调整,实时生效,已支持 NacosApolloZookeeperConsulEtcd,同时也提供 SPI 接口可自定义扩展实现

  • 中间件线程池管理:集成管理常用第三方组件的线程池,已集成TomcatJettyUndertowDubboRocketMqHystrixGrpc 等组件的线程池管理(调参、监控报警)


架构设计

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

  • 配置变更监听模块

  • 服务内部线程池管理模块

  • 三方组件线程池管理模块

  • 监控模块

  • 通知告警模块

代码结构

图片

  1. adapter 模块:主要是适配一些第三方组件的线程池管理,目前已经实现的有 SpringBoot 内置的三大 web 容器(TomcatJettyUndertow)、DubboRocketMqHystrixGrpc 的线程池管理, 后续会接入其他常用组件的线程池管理。

  2. common 模块:主要是一些各个模板都会用到的类,解耦依赖,复用代码,大家日常开发中可能也经常会这样做。

  3. core 模块:该框架的核心代码都在这个模块里,包括动态调整参数,监控报警,以及串联整个项目流程都在此。

  4. example 模块:提供一个简单使用示例,方便使用者参照

  5. extension 模块:放一些扩展功能实现,比如基于 redis 的流控扩展、邮件发送扩展、skywalking 上下文传递扩展等

  6. logging 模块:用于配置框架内部日志的输出,目前主要用于输出线程池监控指标数据到指定文件

  7. starter模块:提供独立功能模块的依赖封装、自动配置等相关。

配置变更监听模块

1.监听特定配置中心的指定配置文件(已实现 NacosApolloZookeeperConsulEtcd),可通过内部提供的SPI接口扩展其他实现。插播一条:如果你想加入我们,可以点击->程序员交流社区

2.解析配置文件内容,内置实现 ymlpropertiesjson 配置文件的解析,可通过内部提供的 SPI 接口扩展其他实现

3.通知线程池管理模块实现参数的刷新

服务内部线程池管理模块

1.服务启动时从配置中心拉取配置,生成线程池实例注册到内部线程池注册中心以及 Spring 容器中

2.接受配置监听模块的刷新事件,实现线程池参数的刷新

3.代码中通过依赖注入(推荐)或者 DtpRegistry.getDtpExecutor() 方法根据线程池名称来获取线程池实例

三方组件线程池管理

1.服务启动获取第三方中间件的线程池,被框架管理起来

2.接受参数刷新、指标收集、通知报警事件,进行相应的处理

监控模块

实现监控指标采集以及输出,默认提供以下三种方式,也可通过内部提供的 SPI 接口扩展其他实现

  • 默认实现 JsonLog 输出到磁盘,可以自己采集解析日志,存储展示

  • MicroMeter采集,引入 MicroMeter 相关依赖,暴露相关端点,采集指标数据,结合 Grafana 做监控大盘

  • 暴雷自定义 Endpoint 端点(dynamic-tp),可通过 http 方式实时访问

通知告警模块

对接办公平台,实现通知告警功能,已支持钉钉、企微、飞书、邮件,可通过内部提供的 SPI 接口扩展其他实现,通知告警类型如下

  • 线程池主要参数变更通知

  • 阻塞队列容量达到设置的告警阈值

  • 线程池活性达到设置的告警阈值

  • 触发拒绝策略告警,格式:A/B,A:该报警项前后两次报警区间累加数量,B:该报警项累计总数

  • 任务执行超时告警,格式:A/B,A:该报警项前后两次报警区间累加数量,B:该报警项累计总数

  • 任务等待超时告警,格式:A/B,A:该报警项前后两次报警区间累加数量,B:该报警项累计总数

图片

图片

图片

开源地址

https://github.com/dromara/dynamic-tp

标签:报警,监控,实现,美团,配置,线程,模块,动态
From: https://blog.csdn.net/cgk_ALEM/article/details/145106197

相关文章

  • 【前端】自学基础算法 -- 25.动态规划-01背包问题
    动态规划-01背包问题简介动态规划(DynamicProgramming,简称DP)是一种解决复杂问题的方法,它将问题分解为更小、更简单的子问题,并存储这些子问题的解,以避免重复计算。动态规划通常用于优化问题,如求最大值、最小值或计数问题。动态规划的基本思想是将大问题分解为小问题,并从......
  • 线程每次iodelay监控及D状态开始和结束监控并做堆栈记录
    一、背景在之前的博客 获取进程或线程级别的iodelay的方法_io验证延时链-CSDN博客里,我们讲到了获取进程或线程的iodelay的方法,但是博客里讲到的获取iodelay的值是一个累积值,并不能准确的捕获到每个单次的iodelay具体是多少。这篇博客里是为了监控每个单次的iodelay,除了监控i......
  • Java反射、静态代理、动态代理
    概述反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。Spring、mybatis、动态代理、注解都是使用了反射。优点:可以让......
  • Java多进程多线程处理详解
    在Java编程中,多进程和多线程是两种常见的并发编程技术,用于提高程序的执行效率和响应速度。本文将详细介绍Java中的多进程和多线程处理,包括理论概述和代码示例。通过本文,你将了解如何在Java中实现多进程和多线程,以及它们在实际应用中的价值和意义。一、理论概述1.多进程与多线程......
  • 封装按钮信息与按钮数量动态显示与提示信息并进行触发按钮组件
    标题:封装弹框并点击动态按钮组件进行触发功能:封装按钮信息与按钮数量动态显示组件页面:按钮信息与按钮数量动态显示,提示信息不固定封装组件页面: <template><el-dialogv-model="dialogVisible"class="stepCustom-dialogcustom-dialog-center"destroy-on-closeheight=......
  • Inxpect毫米波安全雷达:精准检测与动态保护,工业自动化可靠选择
    Inxpect毫米波安全雷达具备“精准检测、动态区域保护、环境适应性”三大核心功能。在工业自动化和机器人系统里,这些功能发挥着重要作用,有助于提升安全性与效率。Inxpect雷达运用毫米波技术,在诸如存在灰尘、烟雾或碎屑等复杂环境中,也能保持稳定的检测能力。精准检测高精度......
  • 【IO编程】静态库 和 动态库
    在软件开发中,库是一组已编译的代码集合,提供了程序可以直接调用的功能模块(如数学运算、字符串处理、文件操作等)。库的主要作用是提高代码复用性、减少重复开发,并提供标准化功能。什么是库库(Library)是一个包含函数、类或其他可重用代码的集合。开发者在程序中调用库中的函......
  • 如何理解C语言之动态内存管理
     目录1.为什么要有动态内存分配2.malloc 和free2.1malloc2.2free3.calloc和realloc3.1calloc3.2realloc4.常⻅的动态内存的错误4.1对NULL指针的解引⽤操作4.2对动态开辟空间的越界访问 4.3对⾮动态开辟内存使⽤free释放4.4使⽤free释放⼀块动态......
  • 互联网大中小厂实习面经:滴滴、美团、货拉拉、蔚来、信通院等
      本文介绍Momenta、蔚来、中国信息通信研究院、昆仑万维、滴滴、易智瑞等企业各类技术岗位的暑期实习、日常实习面试流程与具体问题。  在前一段时间(2024年03月更新:这里的前一段时间指的是一年前,也就是差不多2023年的上半年;暑期实习、日常实习就是差不多每年春天前开始投递......
  • SpringCloud 配置动态更新原理深度解析
    引言在现代微服务架构中,服务数量庞大、功能复杂、配置参数众多。如何有效管理和动态更新配置成为微服务开发中的一个重要挑战。SpringCloudConfig作为一种分布式配置管理解决方案,能够集中存储和管理配置文件,同时支持配置的动态更新。这种动态更新机制极大地减少了因配置变......