文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

深度剖析动态线程池的九大场景

2024-12-01 13:57

关注

线程池是一种基于 池化思想管理线程 的工具,使用线程池可以减少 创建销毁线程的开销,避免线程过多导致 系统资源耗尽。在 高并发以及大批量 的任务处理场景,线程池的使用是必不可少的。

如果有在项目中实际使用线程池,相信你可能会遇到以下痛点:

  1. 线程池随便定义,线程资源过多,造成服务器高负载。
  2. 线程池参数不易评估,随着业务的并发提升,业务面临出现故障的风险。
  3. 线程池任务执行时间超过平均执行周期,开发人员无法感知。
  4. 线程池任务堆积,触发拒绝策略,影响既有业务正常运行。
  5. 当业务出现超时、熔断等问题时,因为没有监控,无法确定是不是线程池引起。
  6. 原生线程池不支持运行时变量的传递,比如 MDC 上下文遇到线程池就 GG。
  7. 当项目关闭时,无法做到优雅退出,大量正在运行的线程池任务被丢弃。
  8. 线程池运行中,任务执行停止,怀疑发生死锁或执行耗时操作,但是无从下手。

基于以上诸多痛点,小马哥着手 hippo4j 的开发,致力于打造标准线程池 动态变更 和 监控 的中间件框架。

GitHub:​https://github.com/opengoofy/hippo4j​

Gitee:​https://gitee.com/agentart/hippo4j​

hippo4j 通过对 JDK ThreadPoolExecutor 线程池增强,以及扩展三方框架底层线程池等功能,为业务系统提高线上运行保障能力。

小贴士:hippo4j 不止于 Java ThreadPoolExecutor 的增强,​​Dubbo​​、​​RabbitMQ​​、​​RocketMQ​​、​​Hystrix​​、​​Tomcat​​、​​Jetty​​、​​Undertow​​ 等框架线程池也都有进行监控和动态变更。

1. 线程池随意定义,造成服务器高负载

在系统开发的过程中,因为涉及到多人协作,难免会出现信息不互通的情况。在同一个系统,对于线程池来说,常见的是线程池随意定义。

随着系统不断开发,相同或不同语义的线程池被定义得越来越多,间接导致服务器资源严重耗损。

而如果系统中使用 hippo4j,能够在控制台查看当前应用已有线程池,是否存在相同语义且业务可复用线程池实例,避免线程资源过度浪费。

2. 线程池参数不易评估

业务中使用了线程池,十个程序员可能有九个都在犯嘀咕,这线程池的配置应该如何选择?

我觉得犯纠结的点主要有两个,无外乎设置的数多了或者少了。

大家都知道,如果要修改运行中应用线程池参数,需要停止线上应用,调整成功后再发布,而这个过程异常的繁琐,如果能在运行中动态调整线程池的参数多好。

美团技术团队基于这些痛点,推出了动态线程池的概念,催生了一批动态线程池框架,hippo4j 也是其一。

如果应用是集群部署,hippo4j 可以选择修改线程池 某一实例,或者修改 集群全部实例,运行时生效,不需要再重启服务。

再比如,压测时使用 hippo4j 动态调整线程池参数,对于开发测试来说,也是个不错的选择。

3. 线程池运行时报警策略

从线程池运行时监控的角度出发,hippo4j 内置 4 种报警策略,线程池活跃度、阻塞队列容量、拒绝策略触发以及任务运行超时报警。

hippo4j 支持钉钉、企业微信和飞书软件通知,线程池任务运行超时报警示例:

4. 线程池运行时状态对开发者黑盒

线程池在服务运行过程中,对开发者来说是一个完全的黑盒。开发者无法得知线程池的参数变化,比如阻塞队列数量或者完成任务数等核心参数,这对于排查问题来说并不友好。

hippo4j 支持线程池运行时状态实时查看,并在核心参数的基础上扩展了 负载、内存以及拒绝次数 等关键指标,每次查询返回线程池当前运行信息。

5. 线程池监控

hippo4j 提供了两种线程池运行时数据监控方式,分别是:

(1)内置数据池数据采集 + 监控,无需依赖任何中间件,由 hippo4j 内部集成的方式运行。

(2)使用三方中间件 Prometheus + Grafana 或 ElasticSearch + Grafana 采集和监控。

6. 整合 Spring ThreadPoolTaskExecutor

Spring ​​ThreadPoolTaskExecutor​​ 对原生线程池扩展了一部分功能,我认为比较实用有两个,并且 hippo4j 也已经支持。

  1. 当服务停止时,通知线程池处理剩余任务,并在等待指定时间后强制停止。
  2. 传递线程上下文到线程池执行上下文中。

第一个是实际使用中很核心的功能,减少了线程池丢弃任务的可能,这里重点说明下。

我们平时在停止应用时,有没有这样一个考虑,线程池中的任务真的都执行完成了吗?

可能执行完了,可能没有

Spring 基于以上考虑,注册了线程池销毁方法。在应用关闭时,如果发现线程池存在任务没有执行完,需要等待一个指定时间。指定时间内任务执行如果执行完毕,皆大欢喜;如果还存在没有结束的任务,则丢弃。

为什么会丢弃任务而不是再等等?

因为如果线程池任务长时间执行,会影响整个应用的停止,进行了折中处理。

7. 三方框架中间件线程池适配

hippo4j 的目标是兼容所有框架的线程池,并可以提供监控和动态修改的能力。

目前已支持的三方框架线程池列表:

支持上述框架线程池的动态变更参数和监控功能,比如:

未来 hippo4j 会支持更多三方框架线程池,如果你有好的想法也可以和我沟通。

8. 线程池运行堆栈查看

线程池运行中,任务运行停止,怀疑发生死锁或执行耗时操作。大多数程序员会选择使用命令或者 arthas 查看线程池运行中线程的堆栈,看看其中的 Worker 都在哪个方法卡住了。

hippo4j 基于以上痛点,推出了线程池运行堆栈实时查看功能。

9. 动态线程池对性能有无影响

这可能是很多开发者担心的一个点,在这里统一回复下。

hippo4j 仅对线程池做部分核心功能增强,没有修改任务执行源代码流程,可以保证绝对的安全。

其次,hippo4j 上述的功能,都是与线程池执行任务主流程外扩展的,不会影响线程池正常的执行性能。

hippo4j 为用户提供了两种运行模式,分别是轻量级的配置中心接入,和功能更齐全的服务端接入,下面都来说说各自的优缺点。

1. hippo4j config

依赖配置中心完成线程池的动态变更,已支持的配置中心有:Nacos、Apollo、Zookeeper、Etcd,未来还会接入 Consul 等。

另外,hippo4j 已支持用户自定义配置中心实现,如果使用公司自研或其它配置中心,也可以极小工作量进行引入。

使用 hippo4j config 模式的优点和不足:

2. hippo4j server

需要部署 hippo4j Jar 包,涵盖上文中描述的所有功能。

因为服务端内部实现了配置中心和注册中心(参考 nacos 和 eureka 实现),所以它不依赖任何三方中间件。

如果最初使用 hippo4j config,想要切换到 server,两者在进行替换的时候,无需修改业务代码

使用建议:根据公司情况选择,如果基本功能可以满足使用,选择 hippo4j config 使用即可;如果希望更多的功能,可以选择 hippo4j server。

开源项目发展离不开用户和贡献者的支持,小马哥梳理出最近 hippo4j 发展近况:

最后总结下,作者在每天下班和周六日的时间做开源项目,妥妥的为爱发电。如果各位大佬觉得有用,麻烦在以下平台 star 支持,非常感谢~

GitHub:​https://github.com/opengoofy/hippo4j​

Gitee:​https://gitee.com/agentart/hippo4j​

来源:龙台的技术笔记内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯