线程池参数设置法则

45 阅读6分钟

怎么根据线程池告警修改线程池参数

前置:

  1. 使用spring项目进行开发
  2. 使用线程池进行项目开发
  3. 有dynamic-tp或者Hippo4J或者其他有以下告警检测的工具对线程池进行监控
  4. (最好)有运维团队或者运维方面配置

任务:

  1. 触发告警后怎么修改线程池参数和线程池告警参数(重要)
  2. 有哪些需要的线程池告警
  3. 线程池告警阈值和线程池参数怎么设置
  4. 触发告警后怎么排查
  5. 怎么根据业务增长重新修改资源与线程池参数

常见线程池告警类型如下,本文也从以下几个方面进行展示:

image.png

1、触发告警后怎么修改线程池参数和线程池告警参数

先说结论:

根据线程池告警修改参数导图:

image.png

1.1、线程活跃度告警

释义:任务过多,使得线程池中活跃线程占比超过阈值(如99%)

如果核心线程数>最大线程数*80%:该告警基本上无用,可以不使用

如果核心线程数占最大线程数较小:该告警有一定用处,但是不如其他线程池告警

1.2、队列容量告警

释义:任务过多,达到任务队列容量的阈值(如70%)

  1. 如果是任务逐渐处理不过来:

    增加pod,增加核心线程数最大线程数,增加任务队列容量

    如果是突发任务:

    增加任务队列大小容量

1.3、拒绝策略告警

释义:任务过多,线程数量达到最大,且任务队列已满,触发线程池拒绝策略

  1. (线程池告警)降低队列容量告警阈值

    增加 任务排队超时告警、任务执行超时告警

  2. 如果是任务逐渐处理不过来:

    增加pod,增加核心线程数最大线程数,增加任务队列容量

    如果是突发任务:

    增加任务队列大小容量

  3. 优化拒绝策略,尝试自定义拒绝策略(从Netty、Dubbo等框架中学习非JDK8的拒绝策略)

1.4、任务排队超时告警

释义:任务从任务队列到线程池中时,时间过长

优化点:

  1. 增加核心线程数与最大线程数(如原有数量*2)

  2. (其他)单个任务逻辑,优化可以从异步,并发等方面入手

    增加pod数量

1.5、任务执行超时告警

释义:执行期间单个任务直接放入线程中执行,但是整个执行期间过长。

优化点有以下:

  1. (线程池告警)该线程池的任务队列告警阈值需要降低阈值优化,如果是核心业务,则需要减少降低限度(如5%),直至可以在运维发现问题后,有足够时间让开发排查;如果不是核心业务,则可以随便修改,甚至不修改

  2. (线程池参数)增加任务队列容量,如果遇到任务激增,则可以尽量避免触发拒绝策略

    线程存活时间可以增加(1000~10000之间是业务上比较合理的数值),避免比核心线程数多的对应数量线程

    增加核心线程数与最大线程数(如原有数量*2)

  3. (其他)单个任务逻辑,优化可以从异步,并发等方面入手

    启动时预热全部核心线程数量,避免创建线程导致任务消耗时间增加

    增加pod数量

2、有哪些需要的线程池告警

调参通知、队列容量告警、拒绝策略告警必然是需要的 核心微服务: 必须加上 调参通知、队列容量告警、拒绝策略告警 如果是对于设备时效性要求较高=>加上 任务排队超时告警、任务执行超时告警 如果是长任务=>加上 任务执行超时告警、线程池活跃度告警

非核心为服务: 一般只需要 调参通知、队列容量告警、拒绝策略告警,后续根据业务需要增加

告警阈值怎么设定?

  1. 可以优先按照线程池框架的默认阈值
  2. 触发频率可以先按照线程池框架的默认阈值
  3. 可以依据部门要求加上其他要求,后续根据线上实践及时修改
  4. 如果需要告警触发频率限流则需要开发同事新增代码实现

3、线程池告警阈值和线程池参数怎么设置

线程池有以下几种形式:

  1. 线程池为单个spring项目公用、或者是全部服务只有2个线程池,CPU密集型线程池与IO密集型线程池
  2. 线程池根据不同业务分为多个线程池,且父线程与子线程在不同线程池中执行

推荐使用方式2

优先基于一些理论得到合适一些的线程池参数

img

核心微服务:

基于计算得到的理论线程池参数根据Jmeter进行压侧微调,直至获得最合适的线程池参数,具体方式可以通过二分调参,下一次调参数值是上一次调参修改量的1/2

以上是理论上的线程池参数,为了可以更好地使用线程池,还需要根据压力测试对线程池参数进行微调,直至可以获得能最大限度利用资源的。 压测-压测报告对比-调参-再压测。。。重复循环,直到获取到最优的线程池参数配置。

非核心微服务:

不如直接根据理论值配好上线,如果有压力可以立刻增加资源、修改线程池参数。 可有可无的微服务,要避免浪费资源,也需要线程池监控查看配置,此时线程池情况可以做一个较好的缩容的指标。

4、触发告警后怎么进行排查

首先需要明确一下几点:

  1. 收到告警时,需要先看告警是否配置正常
  2. 偶发告警基本上不需要关注,只有遇到持续性告警才需要介入处理

排查思路大概如下:

36acdd9e5dac3d25f4463b42778cfbec.png

5、怎么根据业务增长重新修改资源与线程池参数

需要关注的点:

  1. 业务增长怎么转换成可以量化的“需要新增的资源量”

  2. 业务增长后,可以依据原有微调后的参数等比例修改,后再进行压侧/根据实际业务微调参数 核心微服务可以根据压测修改,非核心业务可以根据CPU核数重新计算。

  3. 业务增长后,监控项是否需要增减,是否需要改阈值 监控项需要根据业务特性是否发生变更做更改;

    阈值由于是一个百分比,可以不变,后续再根据业务预警做修改。

6、推荐阅读

  1. Java线程池实现原理及其在美团业务中的实践
  2. 线程数突增!领导说再这么写就gc掉我
  3. 我决定蹭一下“线程数突增...”这篇文章的热度。