线程池优化与监控

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

一、前言

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

线程池优化与监控 2

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

    二、整体设计

    目标:

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

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

      分离:

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

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

      具体的策略包括:

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

      监控:

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

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

      三、技术实现

      2.1 线程管理库

      目标:

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

线程库结构图

线程池优化与监控 8

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

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

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

3.2 轮询任务统一

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

线程池优化与监控 14

线程池优化与监控 16

任务过滤:

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

异常任务过滤的实现:

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

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

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

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

    四、工程更改

    工程更改主要分为 5 块:

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

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

    五、信息采集与监控

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

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

      改善效果:

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

    3. 六、未来规划

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

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

(0)
上一篇 2023年4月3日 下午3:49
下一篇 2023年4月3日 下午4:12

相关推荐

  • 爱思助手刷机教程图片(爱思助手三种刷机模式的区别)

    如果你是 iPhone 用户,建议你下载一个 爱思助手 哦。 手机在日常使用过程,内存使用容量也会不断添加,当手机内存使用容量达到一定程序后会导致手机突然关机并开不了机,保留资料去刷机提示无法恢复设备(-1110) 现在爱思助手的修复刷机功能可以帮用户解决手机内存不够但是又想保存资料刷机这个问题。 下面是详细操作教程。 第 1 步,打开爱思助手,将爱思助手更…

    2023年4月3日 下午4:06
    21
  • eclipse安装教程详细教程(安装eclipse步骤与配置)

    Eclipse是一个基于Java环境的软件开发平台,主要支持的是Java语言,Eclipse使Java编程人员在编写程序时更加方便简洁。如果想要学习使用Java的新手,这是一款很不错的软件。 那要如何下载并安装使用eclipse呢?本篇文章将为大家详细讲解,如果对你有帮助,记得转发关注哦~~ 搭配视频观看效果更佳~~ https://www.ixigua.c…

    2023年4月3日 下午4:06
    21
  • 官方原版win10安装教程(原版系统安装详细步骤)

    众所周知,当电脑出现问题,重启能解决50%,重装系统能解决90%,买台新的能解决100%。而重启电脑和再买一台新的电脑相比,无疑是最快捷方便的方法。 重装系统目前有两种方式进行安装,一种是通过PE辅助安装,好处就是便捷方便,而且有很多功能和软件可以在PE下使用。 但是如果使用的PE制作工具或者封装的系统没选好,可能会会夹带一些奇怪的软件或者全家桶,用不了多久…

    2023年4月3日 下午4:06
    21
  • java入门基础知识(java语言基础知识总结)

    经常在知乎看到一个问题:Java学到什么程度可以算是精通? 今天就围绕这个问题,其实学习 Java 学到什么程度算是精通,这个其实没有盖棺定论的,也不是说你拿个年薪几十万的 offer 就可以自诩精通了。 我认为,如果市面上这些资料、书籍你都啃的差不多,你能在所有的 Java 程序员中跻身前 0.1% 的话,你就可以达到”精通” 这个…

    2023年4月3日 下午4:06
    21
  • 剪纸教程图解步骤(剪纸教程图解步骤简单)

    今天给大家带来的是——简单枫叶剪纸教程。有多简单呢?只需要一张纸,一把剪刀,而且只需要剪一下就可以了。有没有一丝心动,感兴趣的话就快来试试吧!这个枫叶剪纸作为装饰非常不错哦! 枫叶剪纸教程图解 先上图 我们需要准备的材料有:一张正方形的纸,我用的是10厘米正方形纸,供大家参考。除此之外还有剪刀。 取出正方形纸,沿着中间对折。 然后按如图所示,再次向中间折叠。…

    2023年4月3日 下午4:06
    21
  • 无线监控安装教程(无线监控安装教程图片)

    视频监控就像我们的第三只眼睛,应用越来越广范,不管是公共场所,还是家用,随处可看到监控探头的影子。 有时候我们需要在家里装一两个监控,但数量少,找专业人士又不划算,那咱们可以自己学学自己动手装,超级简单,一学就会。下面咱们跟着截图一步步学。以有线网络摄像头为例。 第一步:组装好摄像头,安装到需要的位置,连接好网线和电源线,电源为12V直流供电,可以用集中电源…

    2023年4月3日 下午4:06
    21
  • 让远程成为本地,微服务后端开发的福音

    微服务后端开发的最大痛点之一就是调试困难,非常影响我们的开发效率。 如果我们想与其他微服务进行联动调试,则需要在本地环境中启动对应的微服务模块,这可能需要大量的配置和构建时间,同时也会占用我们本地很多资源,可能还会出现”带不动“的情况。 虽然说我们可以在测试服务器上进行调试,但整个流程也是比较漫长,提交代码 -> 触发CI/CD -> 等待构建成…

    2023年4月3日 下午4:06
    21
  • 记一次 CesiumJS 中非 4326/3857 WMTS 数据的加载

    CesiumJS 能用的 WMTS 目前只支持两种切片方案(TilingScheme): 0 级瓦片有 2 个的 GeographicTilingScheme 0 级瓦片只有 1 个的 WebMercatorTilingScheme 光说很抽象,上图: 0 级瓦片有 2 个的投影,是直接以经纬度数值展平成平面,众所周知: 纬度跨度:经度跨度=180:360=…

    2023年4月3日 下午4:06
    21
  • 电脑组装教程图解插头(电脑主机插线安装步骤图)

    对于没有任何硬件安装基础的小伙伴来说,如果想要自己组装一台电脑主机,是一件相对比较困难的事情,毕竟隔行如隔山,但是就是有一些动手能力强的人群,通过一篇详细的DIY电脑组装教程就可以将自己选择的硬件组装出一台完整的电脑。装机之家晓龙为广大粉丝编写过几篇十分详细的电脑装机教程,基本都是图文版的,全网至少达到了上千万浏览量,受到了广大网友的一致好评。不过也有网友表…

    2023年4月3日 下午4:06
    21
  • OPPO 大数据诊断平台“罗盘”正式开源

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

    2023年4月3日 下午4:06
    21