29

记一次线上 GC 告警处理过程

 4 years ago
source link: https://www.tuicool.com/articles/YVvM3a7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文来自公众号:程序员私房菜

作者:武哥

已获得转载授权

ARbMvae.gif

阅读本文约需要5分钟

就在上周,晚上下班后在家上厕所,突然微信企业邮箱收到线上GC告警了:G1 Young Generation Count 超过阈值。我菊花一紧,裤子还没来得及提。这是我入职拼多多后第一次遇到的线上告警。

从告警提示来看,是新生代垃圾回收次数过多,换种角度想想,应该是代码中某个地方创建了太多的对象,而且很快就被回收。由于电脑没装 VPN,只能第二天去公司看看了。

1. 调度出问题了?

第二天到公司,吃过饭大概1点左右又告警了一次。从CAT监控平台看,确实有两次高峰,而且超过阈值。初步判断,可能是调度不均匀导致的,因为这不是那种必现的频繁告警。只要调度均匀,线上几台机器各自分担点,其实也还好。因为确实有这种可能,某个时刻都调度到某一台机器了,导致负载太大,大量的创建和回收对象。

我正准备去找调度那边的同事咨询。老大跟我说,有没有可能是任务本身的问题?也就是说不管调度到哪台机器执行,它都会告警,任务本身就有问题。我觉得也有道理。

2. 问题的定位

因为告警的服务是我的定时任务,这个服务里有三十几个定时任务在被调度。所以首先我得找到是哪个定时任务出的问题,于是我根据告警时间,去线上的可视化日志平台调取两次告警前后的日志。

结合代码 Command 接口的日志提示,根据关键词快速搜索出打印的 Command 日志(如果不懂 Command,可以看下这篇文章: 程序员除了会CRUD之外,还应该知道什么叫CQRS! ),因为我只要定位到了 Command,就好定位是哪个任务了。因为不同类的任务会调用不同的 Command 去执行。

通过两次告警日志的定位,最后分析出是同步广告成交额信息的定时任务出的问题。这个定时任务是干啥的呢?首先去今日头条拉取今天、昨天、前天和大前天的广告交易额数据,然后重新封装,上报到其他数据平台。问题就在于这中间的重新封装,会创建大量的对象。

要知道拼多多的交易额数据是非常多的。虽然已经在代码里限定了同步粒度是1000条一次,但是还是非常频繁的创建和销毁对象。而且数据必须重新封装,这是无法避免的,那怎么解决呢?

3. 将任务拆分

第一反应就是将原来的任务拆分,粒度拆分更细一点。什么意思呢?比如原来同步昨天、前天和大前天的数据是放在一个任务里执行的,那我拆成三个任务去执行。如下图:

rMviumz.jpg!web

因为拆分任务后,三个任务都会被调度的,不同的任务就有可能被调度到不同的机器去执行,这总比在一台机器上执行要好很多。这是从任务粒度的角度去解决,把任务分的更细,这个方案是可行的,也是有效果的。

但是就在昨天,又一次告警了……说明把任务拆分后,虽然可以降低负载,但是仍然没法满足预设的阈值。

4. 将任务分片

上面说的把任务拆分,指的是拆分后,每个任务会被调度到某台机器去执行。那么将任务分片是什么意思呢?任务分片指的是,一个任务我让线上所有机器去执行,你执行一点,我执行一点,最后保证一个任务被完整的执行掉即可。如下图:

AVJZRbR.jpg!web

这种思路是非常棒的,公司的Gavin调度平台做的非常好,我学习了一下公司相关的文档,再加上和同事的讨论,搞清楚了这个分片的原理。我简单抽象一下如何将任务分片去让所有机器调度,而且保证任务的完整性。

假如线上有两台机器A和B,我将一个任务分成10片,那么每个机器分到的片数集合可以表示成 [0,1,2,3,4] 和 [5,6,7,8,9]。那么在我的任务里,假设要处理14267条数据(我随便敲的一个数字),每条数据应该都有一个标识,假如就是我们常用的id,那我用id去模10,得到的结果落在哪个集合,就让该集合对应的机器去执行。

这相当于我把这14267条数据给打散了,放到所有机器上去各自执行一点,就像上面图中展示的那样,而且是没有规律的打散。所以我们只要知道分了多少片以及每台机器被分到的片数集合,即可完成这个分片功能。

但是得确保该任务可以被打散执行才可以,比如某个任务需要计算好多个账号在一起的相关费用,那么就不适合这种分片的方式了。所以方式和理念固然重要,但是也要结合实际场景来用。实在不行,那就再加个机器呗!

5. 总结一下

这次告警的处理对我来说,收获蛮大的,主要有几点感触蛮深的。

1)公司有非常强大的监控平台,任何一个微服务的运作情况,都清晰的展现在平台上,而且每人轮流巡视平台,遇到告警,会第一时间告知对应负责人,平台也会自动给负责人发通知。保证第一时间暴露问题。

2)调度平台非常重要,我之前参与的一个项目也有很多定时器,但是缺少一个统一的调度平台,代码里定时器乱飞,这里有个@Scheduled,那里也有个,有时候你根本不知道哪个定时器在执行。

3)文档非常重要,公司规不规范很大一部分取决于自己文档平台的建设,而不是写个word我传给你,你传给我。公司需要有自己的wiki,每个平台有对应的文档,这样沟通和学习,效率更高。

4)在咨询调度相关的问题时,加了公司的Gavin调度技术群,跟管理员学习了很多,公司基础架构都有对应的技术群,遇到问题都会有技术支持,很方便。

zuUnyaE.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK