线程池优化与监控

随着应用不断的迭代更新,零售工程内异步任务逐渐增多,包括网络请求、本地 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

相关推荐

  • 取代C++!微软改用Rust语言重写Win11内核:简洁安全、性能更佳

    快科技4月29日讯,随着微软确定结束对Win10的功能更新,其更多精力将转移到Win11以及“Win12”上。 在日前举办的BlueHat IL 2023 大会上,微软企业和操作系统安全副总裁David Weston介绍了他们正对Win11进行的内核级改造。 简单来说,微软正用Rust取代C++改写内核,目前已经添加了36000行代码。 Weston指出,R…

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

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

    2023年12月18日
    226
  • 我说MySQL每张表最好不超过2000万数据,面试官让我回去等通知?

    事情是这样的 下面是我朋友的面试记录: 面试官:讲一下你实习做了什么。 朋友:我在实习期间做了一个存储用户操作记录的功能,主要是从MQ获取上游服务发送过来的用户操作信息,然后把这些信息存到MySQL里面,提供给数仓的同事使用。 朋友:由于数据量比较大,每天大概有四五千多万条,所以我还给它做了分表的操作。每天定时生成3张表,然后将数据取模分别存到这三张表里,防…

    2023年12月17日
    154
  • 盘发教程简单好看(各种盘发教程)

    换发型如换脸,不少姑娘都深谙其中的道理。所以在换发型这件事情上都是非常的慎重,既然不能经常换发型,却不影响我们在原本的发型之上做出一些改变。比如说俏皮甜美的盘发,既有着优雅的姿态,又更加清爽大方,早就是姑娘们喜欢的风格了。 那么你知道怎么盘头发简单又好看呢?很多姑娘看到别人的盘发非常美,却有自己的不敢动手,其实盘头发没有那么难,今天小疯给大家分享四款俏皮甜美…

    2023年7月31日
    273
  • 手机贴膜教程钢化膜(手机贴膜教程最详细)

    以华为P30pro为例 (贴膜前请关好门窗,确保贴膜环境干净整洁,无灰尘和毛絮干扰) 温馨提示:请一定要在光线充足的环境下进行贴膜操作,以确保看清细节部位。 步骤一:清洁手📱机屏幕 取出酒精湿巾,清洁手📱机屏幕上的污渍。然后再用无尘布把水渍擦拭干净。 步骤二:安装贴膜神器(如无神器可略过) 温馨提示:土真V:lwq520hfj送钢化膜贴膜神器上有字母一端务必…

    2023年7月30日
    291
  • OPPO 大数据诊断平台“罗盘”正式开源

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

    2023年12月17日
    182
  • 初级瑜伽基础入门教程(基础瑜伽入门)

    初学者练瑜伽,总会感觉身体僵硬、身体打不开、很多体式做不到位!其实初接触瑜伽,由于身体肌肉、筋膜都还比较紧张,不适合练习太大幅度的体式,需要循序渐进地练习! 今天分享一套超级适合初学者练习的瑜伽序列,全身都能锻炼到,体式也不难,把这篇文章收藏起来,坚持练习! 1、下蹲式 山式站立,双脚分开略比肩宽 双脚、双膝向外打开约45度 吸气,脊柱延展,呼气,收核心 屈…

    2023年8月2日
    368
  • 魔术教程简单易学初学(简单易学的魔术教程一学就会的那种)

    跟女儿一起玩的一个科学小实验分享给大家:筷子提米 首先,我们要准备的材料是:一个纸杯、一根筷子、若干米和水。 现在我们开始实验: ✈第一步,把米加上水均匀搅拌,水不要太多,只要米感觉有点湿润就行。 ✈第二步,把搅拌好的米装入纸杯,纸杯选普通的一次性杯子即可,不要选杯口太大的那种。 ✈第三步,把筷子插入米中,随意哪头插入均可,用粗的那头插入更容易成功哦。 ✈第…

    2023年7月30日
    215
  • 我的世界新手教程手机(我的世界手机新手入门攻略)

    1.Minecraft Minecraft是一个沙盘游戏,是一个高度自由的游戏。整个游戏没有终点,你可以在世界里任意发挥你的想象力和能力。 生存模式:你需要不断地收集资源,探索世界,寻找食物来生存下来,整个生存模式没有最终目标。死后可以选择复活。 创造模式:你可以飞行,你拥有无限的资源,能够尽情的创造建筑等,甚至是大型红石设备。 冒险模式:你不能破坏与放置方…

    2023年7月31日
    363
  • 凉拌黄瓜的做法简单又好吃(凉拌黄瓜的简单做法)

    夏季胃口不好,如果能做一道爽口的凉拌菜,无论是吃米饭、喝粥、吃面条,都是妥妥的开胃下饭菜~ By *长腿_河马太太* 用料 黄瓜 2根 盐 1勺 醋 1勺 生抽 2勺 白糖 2勺 蒜 5瓣 姜 少许 红剁椒 1勺 干辣椒 3个 花椒 1克 做法步骤 1、1⃣️、黄瓜切成段,放白糖1勺、盐1勺腌制1小时,等黄瓜出水以后倒掉水,再用清水冲洗干净 2、2⃣️、冲洗…

    2023年8月2日
    479