专栏首页Java那些事线上 GC 告警,我是如何解决的?

线上 GC 告警,我是如何解决的?

阅读本文约需要5分钟

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

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

1. 调度出问题了?

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

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

2. 问题的定位

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

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

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

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

3. 将任务拆分

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

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

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

4. 将任务分片

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

这种思路是非常棒的,公司的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调度技术群,跟管理员学习了很多,公司基础架构都有对应的技术群,遇到问题都会有技术支持,很方便。

所以今日话题:你遇到过哪些线上问题?一起交流交流吧!

———— e n d ————

本文分享自微信公众号 - 程序员乔戈里(CXYqiaogeli)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【BATJ面试必会】JAVA面试到底需要掌握什么?【下】

    非对称加密,对称加密 对称加密(Symmetric Cryptography),又称私钥加密

    乔戈里
  • JVM 发生 OOM 的 8 种原因、及解决办法

    1、代码中可能存在大对象分配 2、可能存在内存泄露,导致在多次GC之后,还是无法找到一块足够大的内存容纳当前对象。

    乔戈里
  • 腾讯10年的架构师的算法学习经验分享

    拿到题目后就开始想着怎么写代码,结果写了大半天,发现越写越乱,最后就写不下去了,又或者是,看到题目后,一脸懵逼,完全不知道怎么下手。

    乔戈里
  • MQX任务学习

    MQX也是基于对任务的调度和管理来运行的,所以今天来简单学习下MQX的任务。 MQX像其他操作系统一样,提供对任务的调度和管理,任务是完成一定功能的函数...

    用户1605515
  • 关于任务调度的思考

    其实对于Celery来说,网络上的资源和文档其实还是比较匮乏的,能够坚持坐下来,能够维护起来这样一个项目,确实不易。

    jeanron100
  • 如何设计嵌入式系统?带你理解一个小型嵌入式操作系统的精髓

    1 多任务机制 其实在单一CPU 的情况下,是不存在真正的多任务机制的,存在的只有不同的任务轮流使用CPU,所以本质上还是单任务的。但由于CPU执行速度非常快,...

    刘盼
  • 浅谈分布式集群资源管理系统【二】

    上一篇的文章当中我们简单了解了一下什么是分布式集群资源管理,它的诞生背景和解决的问题是什么,以及它大概有哪些优点和不足。上一章的内容比较表面,没有过多深入原理,...

    TechFlow-承志
  • JavaScript基础——你真的清楚JavaScript是什么吗?

    为前端开发,你是否问过自己或者思考过什么是JavaScript吗?JavaScript有什么特点?如果让你让一句话高度介绍,你会怎么说?小编认为,在你想深入一门...

    前端达人
  • Linux Kernel调度器的过去,现在和未来

    Linux Kernel Development 一书中,关于 Linux 的进程调度器并没有讲解的很全面,只是提到了 CFS 调度器的基本思想和一些实现细节;...

    刘盼
  • Linux Deadline 调度器 - 第一部分:简介与理论背景

    本文中若有任何疏漏错误,有任何建议和意见,请回复内核月谈微信公众号,或通过caspar at linux.alibaba.com或者 tao.ma at lin...

    Linux阅码场

扫码关注云+社区

领取腾讯云代金券