线程池优化与监控

随着应用不断的迭代更新,零售工程内异步任务逐渐增多,包括网络请求、本地 DB 操作、轮询等任务使用的都是同一个线程池,线程池极易打满(比如网络一慢就容易阻塞线程池),导致任务堆积,造成「操作卡顿」的现象。用户看到操作没反应,可能会更频繁的尝试操作,再加上不断轮询的任务,应用的线程池队列会快速积压更多的任务,「卡顿」现象加剧,单一线的线程池已经无法支撑业务需求:

前言

随着应用不断的迭代更新,零售工程内异步任务逐渐增多,包括网络请求、本地 DB 操作、轮询等任务使用的都是同一个线程池,线程池极易打满(比如网络一慢就容易阻塞线程池),导致任务堆积,造成「操作卡顿」的现象。用户看到操作没反应,可能会更频繁的尝试操作,再加上不断轮询的任务,应用的线程池队列会快速积压更多的任务,「卡顿」现象加剧,单一线的线程池已经无法支撑业务需求:

线程池优化与监控

  1. 任务没有隔离,异步任务相互影响主要是长耗时影响短耗时任务
  2. 轮回任务开销大:没有统一的轮询处理方式,业务方需要自己创建线程或线程池(有些干脆就在默认的 I/O 线程池进行轮询),应用中存在大量的自建线程池,增加无谓的资源消耗
  3. 缺少监控:缺乏线程池的监控和日志,线程池的运行状况和健康度无法衡量,一旦出现「卡顿」问题,排查非常困难,完全不知道是哪些任务造成的问题,伤害用户体验的同时,也极大的消耗开发人员的精力线程池优化与监控图注:短时间任务暴涨的情况,在几毫秒内触发多次任务

    二、整体设计

    目标:

    1. 任务隔离,避免耗时任务影响交互
    2. 统一轮询,减少资源开销
    3. 任务监控,防止业务方使用错误
    4. 信息采集与监控,快速定位排查问题线程池优化与监控

      优化的核心在于分离和监控

      分离:

      对原有的 I/O 线程池进行拆分,分离出不适合放在这个线程池的任务,保证 I/O 线程池能对大量、快速的本地任务给予更好的支持,而分离的关键就在于分离出「慢」和「多」的任务:

      • 避免耗时短的任务等待耗时长的任务
      • 避免频繁、大量执行的任务占据大量的线程池资源

      具体的策略包括:

      • 将网络请求的线程分离出来,放入单独的线程池中,避免因网络任务慢阻塞本地的快速任务
      • 将轮询任务分离出来,当轮询的任务耗时过长或者线程池打满的场景下,会极速加剧线程池的恶化,最终让主流程完全瘫痪,轮询任务不适合放在通用的线程池中,通过将它放入通用的轮询任务线程池,统一化的对轮询任务进行管理

      监控:

      除了已知的网络任务&轮询任务需要分离出 I/O 线程池之外,还需要增加对线程池的监控,进一步分离出不适合放在I/O线程池的任务(同样是「慢」和「多」)

      1. 通过监控每个任务执行的时长,分离出长耗时(即「慢」)的任务,分析出是因为逻辑 bug 还是本身的复杂度正常占用,如果是正常占用就考虑是否合适继续放在默认的 I/O 线程池,最终目标是达成对「慢」的优化
      2. 另外零售工程中还存在短时间大量重复任务堆积的现象,当线程池接近或达到负荷状态时,监控线程池中的任务,找到批量的任务,然后进行优化,最终目标是达成对「多」的优化
      3. 通过上面的方式将「慢」的任务分离出去之后,并不代表这样就完事了,这些任务可能会消耗大量的系统资源,所以同样需要统一对这个线程池进行监控(主要是网络任务的监控),把慢网络请求找出来,达到对「慢」的进一步优化
      4. 通过 API 监控业务方使用合理性,比如:使用多线程轮询的合理性

      三、技术实现

      2.1 线程管理库

      目标:

      1. 管理工程内所有线程池与线程创建
      2. 子线程任务监控
      3. 线程池隔离任务分开执行,使用不同线程池执行不同任务
      4. 轮询任务的统一与异常任务的过滤

线程库结构图

线程池优化与监控

线程池管理,目前会提供三种线程池:

  1. 网络线程池:针对网络任务。更改方式:直接在网络库替换业务方无感知
  2. IO 线程池:针对本地异步任务。更改方式:App 启动时 Hook RxJava 线程池替换业务方无感知
  3. 轮询线程池:针对轮询任务,需要业务方的接入

线程池 API 定义线程池优化与监控

3.2 轮询任务统一

  1. 禁止时间间隔小于 1 秒轮询任务,防止高频轮询消耗资源
  2. 所有轮询任务巡检间隔 1 秒检测一次
  3. 轮询检测是独立的线程,只做轮询检测,有任务时死循环间隔检测,没有任务时则睡眠等待下次注册执行,根据结果轮询执行或睡眠
  4. 线程任务模式有两种:
    单线程回调: 表示最多占用一个线程。例:1 秒轮询回调 1 次,再回调前会判断上个任务是执行完成,如果没有执行完成则回调 pollTaskExceptionCallback(),如果已经执行完成则回调 pollTaskCallback()
    多线程回调:表示最多占用 30 个线程。例:1 秒轮询回调 1 次,再回调前会判断当前任务占用线程总量,如果没有执行完成则回pollTaskExceptionCallback(),如果已经执行完成则回调。pollTaskCallback() 默认是单线程回调
  5. 业务方可以指定轮询次数,或设置无限轮询
  6. 轮询线程池动态扩容:初始线程为 30 个,如果使用线程等于核心线程则动态扩容 2 倍,最大限制 120 个核心线程线程池优化与监控

线程池优化与监控

线程池优化与监控

任务过滤:

轮询正常回调 pollTaskCallback() 方法,如果异常这时将回调到 pollTaskExceptionCallback() 方法。

异常任务过滤的实现:

  1. 记录所有任务。
  2. 每次执行任务时会进行校验,校验监听者是否已经把自己申请的线程全部使用,如果已经全部占用将回调异常方法,直接到任务有一个释放后再继续回调。
  3. 任务执行完后重设记录数据。

轮询异常回调有三种触发场景:

  1. 单线程任务没有释放超时。
  2. 多线程任务占用线程超过最大数量。
  3. 轮询线程池被全部占满超时。

    任务过滤-流程图线程池优化与监控

    四、工程更改

    工程更改主要分为 5 块:

    1. 网关请求线程池的替换,在构建 RxJava observable 替换成自定义网络线程池。
    2. RxJava 默认线程池的替换,App 启动时把 RxJava Hook 设置成自定义 IO 线程池。
    3. 轮询业务接入统一轮询。
    4. 网线线程池使用错误拦截,目的防止线程使用错误,禁止 IO 线程网络请求,通过拦截器方式实现。
    5. 线程任务监听设置给 APM ,通过 APM 分析上报。

    备注:只有轮询需要业务方逐个替代其它都正常使用不感知。

    五、信息采集与监控

    1. 任务提交之后记录每个任务的调用栈信息以及任务提交的时间,之后在任务真正开始执行时会记录任务开始的时间,任务执行完成后即可算出一个任务完整的执行时间、任务等待时间等,这样就可以抓取出「慢」的任务
    2. 在任务执行完成时,如果线程池已满并且任务的等待时间超过阈值,则会拉出线程池任务栈的信息,用于查找出异常的任务

      线程池监听 API线程池优化与监控

      改善效果:

      卡顿定义:包含主线程超过300ms慢方法、ANR、本地子线程操作超过1s、线程池阻塞、页面渲染时间超过200ms。

    3. 六、未来规划

      • 支持更多维度的任务监控,并增加自动报警能力
      • 针对不同的机型进行最优线程池配置,最大化复用系统资源
      • 逐渐完善 pthread、线程任务数量等监控能力

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。商机网仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 tenspace2022@163.com 举报,一经查实,本站将立刻删除。 本文链接:https://www.315965.com/n/52915.html 聚才发 母婴好物

(0)
上一篇 2023年12月15日 上午4:37
下一篇 2023年12月15日 上午4:44

相关推荐

  • 大白菜u盘装系统教程图解(大白菜用u盘装系统的操作全程图解)

    老白菜u盘重装系统步骤,今天教大家用老白菜工具进行系统安装,首先,我们将u盘插入电脑 按开机键然后不停的按u盘启动盘快捷键【f12键】,然后来到老白菜pe引导界面 直接选择win8pe,回车 等待加载pe系统,进入到pe系统后,选择打开老白菜装机pe 选择我们放入的系统镜像文件,选择c盘作为安装的盘符,确定 弹出一键恢复,点击确定 现在就等安装了,安装系统整…

    2023年7月30日
    279
  • 抖音权重下降了怎样快速恢复(三个降权的补救提升方法)

    大家好,我是二小姐,今天是2024年的10月18号那么这里讲一下关于抖音账号的几种不同的权种第一种情况。   很多同学问的最多的一个问题就是说,二小姐你看我这个账号,我这个播放量只有100个,现在还能不能够用,这个账号能不能够用?如果你发了一两百个作品出去,播放量都还是只有几十个,100个,连200个都没有超过,那你最好就换一个账号,因为这个怎么说呢,有些手…

    2023年8月13日
    895
  • 画画教程动漫人物基础(画画教程动漫人物基础入门)

    卡通动画是伴随着每个人的童年,不同年龄阶层的人都有属于自己的卡通回忆,不过有些动画是经典的,也许爸爸妈妈那个年代的动画片,到了10后小宝宝这里还是很热门。今天果果就来教大家花5个动画人物简笔画,非常详细,1分钟速成,零基础都能学会! 皮卡丘 1、首先用线条勾勒出皮卡丘的脸颊。 2、在头部两侧画出皮卡丘长长的耳朵。 3、画出大大的眼睛,留出高光部分。 4、画出…

    2023年7月30日
    289
  • 钢琴初学者指法基本教程(钢琴入门指法教程简单)

    钢琴有多少种指法?经常有琴友经常会问到这个问题。下面来详细介绍一下五种钢琴基本指法。 1、对指 最最基本的是一个手指头正对着一个键盘。五个手指就对应do、re、mi、fa、so五个音。 2、穿指 穿指也叫“拇指潜移”,也有人叫它“钻山洞”,就是1指从2指或3指或4指下面穿过,去弹奏更高的音的指法。 穿指规则: a、只能用1指去穿,而且只能穿2.3.或4指,不…

    2023年7月29日
    303
  • excel表格制作教程入门(excel表格制作教程入门培训)

    打开EXCEL首先是绘制表格,这里就需要你提前想好你需要填写哪些内容,一个内容一个格子。 桌面点击鼠标右键-新建-xls或者xlsx都行 然后可以把鼠标放到新建的表格上边右键-重命名,可以给你的表格取一个适合内容的名称 打开表格(如下图):填入需要做的内容,点击鼠标左键选中内容点击表格选择需要的线框,也可以先点其他边框绘制一个你需要的表格再去填写内容。 接下…

    2023年8月2日
    288
  • OPPO 大数据诊断平台“罗盘”正式开源

    一、背景 OPPO 大数据目前有 20+个服务组件,数据量超 1EB,离线任务数近百万,实时任务数千,数据开发分析师超千人。这也带来了系统复杂度的问题,一方面是用户经常对自己的任务运行状况“摸不着头脑”,不管是性能问题,还是参数配置问题,甚至是一些常见的权限报错问题,都需要咨询给出具体的解决方案;另一方面是面对各类繁杂任务,运维人员经常需要对任务故障定位和排…

    2023年12月17日
    196
  • 快递业企稳回升印证市场回暖

    核心阅读 一季度,我国邮政行业增速逐月向好,整体呈现企稳回升态势。行业实现较快增长,服务质效持续提升,市场活力持续增强……良好的开局,为全年邮政快递业发展奠定了坚实基础,也折射出我国居民消费信心正在增强,经济复苏回暖态势明显。   快递物流,连接千城百业,畅通供需两端,是经济发展的“晴雨表”。今年一季度,我国邮政快递业运行情况如何,全行业呈现哪些新…

    2023年12月23日
    167
  • 科目二练车全程步骤(科目二初学者基本知识)

    当我们交钱进了驾校之后,就可以去练习科目二了。科目一是电脑做题,自己有空看看就行。白天我们要去驾校开始学习科目二。对于我们新手来说,这可能是第一次摸车。因此有很多问题。下面我们就分享新手如何开始学车,科目二新手学车步骤。 刚学车的步骤新手必看 工具/原料 驾校汽车:雪铁龙 方法/步骤 1、科目二考试全程是用一档,脚下要踩的只有离合和刹车。 因此,我们首先要学…

    2023年7月31日
    260
  • 可能是全网最详细的Midjourney基础教程,两万字干货!

    一、前言篇 1. AI 绘图是什么? AI 绘画,顾名思义就是利用人工智能进行绘画,是人工智能生成内容(AIGC)的一个应用场景。其主要原理简单来说就是收集大量已有作品数据,通过算法对它们进行解析,最后再生成新作品,而算法也便是 AI 绘画的核心,是它得以爆火的基础。 1)Midjourney 是什么? Midjourney 是一个由 Midjourney …

    2023年12月18日
    248
  • 英雄联盟新手教程在哪里进入(英雄联盟新手怎么玩)

    此攻是给王者荣耀玩家做的,方便王者荣耀玩家玩英雄联盟手游。 简而言之呢,就是英雄联盟就是全球最火爆的MOBA类游戏,在体验之前我们要了解英雄联盟手游与市面上同类型的手游有什么不同,现在就拿市面上最火的王者荣耀来举例。 分路。 王者荣耀的分路为大龙路、小龙路、中路、野区与辅助(也就是王者荣耀的游走位置),英雄联盟的分路分为上单、中单、打野与双人路(也就是王者荣…

    2023年8月1日
    311