翻车现场:一次JVM FullGC引发的宕机事故

这篇文章给大家聊一次线上生产系统事故的解决经历,其背后代表的是线上生产系统的 JVM FullGC 可能引发的严重故障。

业务场景介绍

先简单说说线上生产系统的一个背景,因为仅仅是文章作为案例来讲,所以弱化大量的业务背景。

简单来说,这是一套分布式系统,系统 A 需要将一个非常核心以及关键的数据通过网络请求,传输给另外一个系统 B。

这里其实就考虑到了一个问题,如果系统 A 刚刚将核心数据传递给了系统 B,结果系统 B 莫名其妙宕机了,岂不是会导致数据丢失?

所以在这个分布式系统的架构设计中,采取了非常经典的一个 Quorum 算法。

这个算法简单来说,就是系统 B 必须要部署奇数个节点,比如说至少部署 3 台机器,或者是 5 台机器,7 台机器,类似这样子。

然后系统 A 每次传输一个数据给系统,都必须要对系统 B 部署的全部机器都发送请求,将一份数据传输给系统B部署的所有机器。

要判定系统 A 对系统 B 的一次数据写是成功的,要求系统 A 必须在指定时间范围内对超过 Quorum 数量的系统 B 所在机器传输成功。

举个例子,假设系统 B 部署了 3 台机器,那么他的 Quorum 数量就是:3 / 2 + 1 = 2,也就是说系统 B 的 Quorum 数量就是:所有机器数量 / 2 + 1。

所以系统 A 要判定一个核心数据是否写成功,如果系统 B 一共部署了 3 台机器的话,那么系统 A 必须在指定时间内收到 2 台系统 B 所在机器返回的写成功的响应。

此时系统 A 才能认为这条数据对系统 B 是写成功了。这个就是所谓的 Quorum 机制。

也就是说,分布式架构下,系统之间传输数据,一个系统要确保自己给另外一个系统传输的数据不会丢失,必须要在指定时间内,收到另外一个系统 Quorum(大多数)数量的机器响应说写成功。

这套机制实际上在很多分布式系统、中间件系统中都有非常广泛的使用,我们线上的分布式系统也是采用了这个 Quorum 机制在两个系统之间传输数据。

给大家上一张图,一起来看一下这套架构长啥样:

image

如上图所示,图中很清晰的展示了系统 A 和系统 B 之间传输一份数据时的 Quorum 机制。

接下来,我们用代码给大家展示一下,上面的 Quorum 写机制在代码层面大概是什么样子的。

PS:因为实际这套机制涉及大量的底层网络传输、通信、容错、优化的东西,所以下面代码经过了大幅度简化,仅仅表达出了一个核心的意思。

image
image

上面就是经过大幅精简后的代码,不过核心的意思是表达清晰了。大家可以仔细看两遍,其实还是很容易弄懂的。

这段代码含义很简单,说白了就是异步开启线程发送数据给系统 B 所有的机器,同时进入一个 while 循环等待系统 B 的 Quorum 数量的机器返回响应结果。

如果超过指定超时时间还没收到预期数量的机器返回结果,那么就判定系统 B 部署的集群出现故障,接着让系统 A 直接退出,相当于系统 A 宕机。

整个代码,就是这么个意思!

问题凸现

光是看代码其实没啥难的,但是问题就在于线上运行的时候,可不是跟你写代码的时候想的一样简单。

有一次线上生产系统运行的过程中,整体系统负载都很平稳,本来是不应该有什么问题,但是结果突然收到报警,说系统 A 突然宕机了。

然后就开始进行排查,左排查右排查,发现系统 B 集群都好好的,不应该有问题。

然后再查查系统 A,发现系统 A 别的地方也没什么问题。最后结合系统 A 自身的日志,以及系统 A 的 JVM FullGC 进行垃圾回收的日志,我们才算是搞清楚了具体的故障原因。

定位问题

其实原因非常的简单,就是系统 A 在线上运行一段时间后,会偶发性的进行长时间 Stop the World 的 JVM FullGC,也就是大面积垃圾回收。

但是,此时会造成系统 A 内部的工作线程大量的卡顿,不再工作。要等 JVM FullGC 结束之后,工作线程才会恢复运作。

我们来看下面那个代码片段:

image

但是这种系统 A 的莫名宕机是不正确的,因为如果没有 JVM FullGC,本来上面那个 if 语句是不会成立的。

它会停顿 1 秒钟进入下一轮 while 循环,接着就可以收到系统 B 返回的 Quorum 数量的结果,这个 while 循环就可以中断,继续运行了。

结果因为出现了 JVM FullGC 卡顿了几十秒,导致莫名其妙就触发了 if 判断的执行,系统 A 莫名其妙就退出宕机了。

所以,线上的 JVM FullGC 导致的系统长时间卡顿,真是造成系统不稳定运行的隐形杀手之一啊!

解决问题

至于上述代码稳定性的优化,也很简单。我们只要在代码里加入一些东西,监控一下上述代码中是否发生了 JVM FullGC。

如果发生了 JVM FullGC,就自动延长 expireTime 就可以了。

比如下面代码的改进:

通过上述代码的改进,就可以有效的优化线上系统的稳定性,保证其在 JVM FullGC 发生的情况下,也不会随意出现异常宕机退出的情况了。


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容