服务器时间同步引发的"惨案"

栏目: 服务器 · 发布时间: 6年前

内容简介:很多时候我们都不用特别的关心服务器时间的问题,比如后台管理系统,如果服务器时间出错顶多会在页面获取错误的时间而已,影响不大。但有些程序对时间非常敏感,不能出一丁点错误,今天要讲的是去年发生在自己身边的事:由于时间同步问题引发了部门级故障,造成非常严重的后果。因为事件发生还不到一年,并且就在自己身边,所以记忆犹新。老规矩,在讲故事之前先了解一下背景,故事中 X 系统后台的简化架构如下:它包括 Client->Connector->Heartbeat 三个模块(当然实际有很多模块,这里省去其他模块简化架构,不影

很多时候我们都不用特别的关心服务器时间的问题,比如后台管理系统,如果服务器时间出错顶多会在页面获取错误的时间而已,影响不大。但有些程序对时间非常敏感,不能出一丁点错误,今天要讲的是去年发生在自己身边的事:由于时间同步问题引发了部门级故障,造成非常严重的后果。因为事件发生还不到一年,并且就在自己身边,所以记忆犹新。老规矩,在讲故事之前先了解一下背景,故事中 X 系统后台的简化架构如下:

服务器时间同步引发的

它包括 Client->Connector->Heartbeat 三个模块(当然实际有很多模块,这里省去其他模块简化架构,不影响问题的描述)

  • Client 是用来采集数据客户端,安装在公司所有的内部机器上,我们称之为 Client 端。
  • Connector 起到 Client 端与后台桥梁的作用,主要用来进行 Client 连接管理、数据透传等。
  • Heartbeat 是心跳模块,用来管理 Client 上报的心跳数据。同时它兼职时间服务器:为 Client 提供统一时间服务。

经过

上图中 Client 模块机器数量 > 万台,Connector 模块机器数量 > 百台,而 Heartbeat 模块机器却只有一台,这是引发惨案的根本原因。事情经过:

  • 某天早上到公司,部门内部已经乱成一团。一番了解后才知道上述 Heartbeat 机器昨晚宕机了,很多心跳数据上报不上来。这时候的问题还只是 Client 上报不了心跳数据而已,并不影响正的常数据采集。
  • 运维开始在一台新机器上部署 Heartbeat 模块,并启动(能自动注册并被发现)。
  • 心跳数据陆续回升,但是只到了正常数量的 60-70%。
  • 各个部门开始向我们部门反映:自己部门的机器 频繁产生 Client 的 core 文件(C++ 程序意外终止时产生的现场文件),而且是大面积的。
  • 开发组老大和相关人获取 core 文件开始分析,一番定位后发现是因为 Client 出现了除零错误,Client 异常退出。异常处的代码大致如下:
int g_lastReportTime = sometime;
void report() {
    int currentTime = getCurrentTime();
    if (somevalue / (currentTime - g_lastReportTime ) > threshold) {
        reportSomething();
        g_lastReportTime = currentTime;
    }
}
复制代码

从上面代码可以看出 currentTime - g_lastReportTime 在理论上是不会等于零的,但是由于新启的机器时间并未与 X 系统内部保持一致。导致 Client 时间回退,也就出现了 currentTime - g_lastReportTime = 0 的情况。

  • 运维立马想到是新 Heartbeat 机器时间问题,由于我们的 X 系统后台都是 Linux 机器,通过 ntpdate 命令将新机器时间统一,并将该命令加入开机启动项。
  • 心跳数据陆续恢复正常。

以上过程花了将近 40多分钟,造成了非常大的影响。后来部门对事故相关责任人进行了问责和全部门通报。这次事故看似偶然,其实必然,从心跳机器单点那一刻。器宕机造成的事故远不及 Client core 造成的严重,可以看出本次事故的主要原因是由于时间不同步造成的,但它也不是孤立的,是众多因素的统一作用结果。本标题服务器时间同步引发的“惨案”并不夸张,希望能引起读者这块的注意和思考。

思考

在事故发生的时候我也没有想太多,毕竟当时作为萌新也想不出来个所以然来。但是随着工作经验积累,慢慢的从这次事故中有了一些总结。这次事故主要引出以下四个问题:

1、监控问题

心跳机器宕机,心跳数据上不来居然在第二天上班的时候才被发现,整整超过 8 小时了。幸亏该系统只是一个内部系统,如果是类似淘宝、天猫这种的,那造成的经济损失和口碑影响可想而知了。听说在半夜监控已经报出异常,但是一个新来的同事定位并未发现问题,才导致了最后的蝴蝶效应。不过好像即使当场发现,如果在切换新机器时没做好时间同步也会出现 core 事故。对于系统监控我有以下几点建议:

  • 不要将重要模块的监控交给新人,很多情况下新人可能并不知道某个监控的重要性
  • 重要模块的监控接收人不要出现“单点”,最好将主管也加入重要模块的监控通知接收人中。
  • 多维度、多地点进行监控,一般一个系统都是一个整体,一旦某个模块出现问题,其他模块也会随之出现问题。如果我们在多个维度、多个地方进行监控,即使某个地方发现不了,总有一个地方能被发现。

2、单点问题

这是一个老生常谈的话题,网上有一堆的解决方案,这里不讲普适性的只介绍下针对 X 系统的。由于该系统的特殊性,Heartbeat 模块并不能进行多机器部署。所以只能单点,那我们只能祈祷单点机器不会发生故障了吗?根据墨菲定律:如果你担心某种情况发生,那么它就更有可能发生。所以不要有侥幸心理,对于 X 系统 Heartbeat 的单点,虽然不能在短时间内重构,但我们还是可以做一些事情而不至于需要运维手动切换机器的。一种方案如下:

在服务注册中心对 Heartbeat 模块机器进行监控,如果发现服务注册中心没有了心跳模块超过一定时间。则启动备用机器上的 Heartbeat 并发出告警。这样就能及时的切换到备用 Heartbeat 不至于太匆忙忘这忘那。简单结构图如下:

服务器时间同步引发的

3、代码质量问题

事故中的错误代码是我简化后的,一般不会出现出现这种低级错误,应该是一段逻辑处理后产生了类似的代码,只是不够直接没被发现。这种情况我们怎么保证代码质量问题?我觉得可以从三个方面考虑:

  • 程序员自测:程序员在写完代码后一定要进行充分自测,虽然不能 100% 保证不出错,但起码能发现大部分的逻辑错误和低级错误。不要想着会有测试帮你,自己就可以偷懒,他们往往只在使用层面进行测试而不是在代码层面。如果不给你配备专门的测试,那就更应该自己动手、丰衣足食了。
  • 代码评审(CodeReview):都说不识庐山真面目,只缘生在此山中。代码检查也是,自己检查自己的代码,很难发现一些隐藏的错误。这时就要其他人帮你检查,也就是 CodeReview。当然,所有的代码都进行 CodeReview 是一件费时费力的事,所以要有选择的进行。一些核心模块的代码,一定要一遍又一遍的自测、CodeReview。至于 CodeReview 的方案试情况而定。
  • 增加专业测试人员:(1) 和 (2) 只能解决代码层面的错误,但是一些使用层面的、极端情况下的错误 (1) 和 (2) 并不一定能发现。所以需要专业的测试人员和测试平台对上线前的代码进行充分测试。

4、分布式或者集群时间同步问题

分布式或者集群的时间同步也是分布式系统下需要解决的问题之一,抛开 X 系统事故中的场景不说。有很多场景是需要保持分布式系统中各个节点(机器)上的时间一致的的,比如银行交易系统,不能让后一笔交易的时间比前一笔交易的时间早,否则会给用户造成困扰。不同的分布式系统有不同的解决方案,有的简单有的复杂。简单的像 X 系统一样直接用 ntpdate 就可以实现,复杂的参考博客园这篇文章《分布式系统----时钟同步》实现自己的同步系统。

当然,以上只是泛泛而谈,权当抛砖引玉。不知道你所维护的系统中是否也存在类似的问题呢? 早一点把已知的问题暴露出来,比藏着掖着要好的多。在出事故之前发现问题能赢得老板对你好感,说不定还能升职加薪,而如果在出事之后再来解决问题那就只能背锅咯


以上所述就是小编给大家介绍的《服务器时间同步引发的"惨案"》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Measure What Matters

Measure What Matters

John Doerr / Portfolio / 2018-4-24 / GBP 19.67

In the fall of 1999, John Doerr met with the founders of a start-up he’d just given $11.8 million, the biggest investment of his career. Larry Page and Sergey Brin had amazing technology, entrepreneur......一起来看看 《Measure What Matters》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具