听过闰年闰月,听过闰秒吗?
闰年闰月大家都知道,可是你听说过闰秒这回事情吗?
闰年是为了弥补是我们的历法 365 天和地球实际公转 365.25 天的差距,所以每 4 年会一年是闰年,多出来的那一天就是 2 月 29 日。
闰月则是和阴历有关,不同于阳历的以公转制定的方式,阴历以月亮绕地球的时间来计算,所以会和阳历的 365.25 天相差 10 天 21 小时,于是,多出来的时间累积下来凑成一个月,也就是闰月了。
那么什么是闰秒?闰秒会带来什么影响?怎么解决闰秒带来的问题?
闰秒定义
要了解闰秒,首先需要了解几个基本的概念。
平均太阳日:天空中的太阳连续两次出现最大仰角(90 度)所经历的时间就是一个太阳日,而又由于太阳日的长短不同,所以取一年内的太阳日平均值,所以可以大致的认为一个平均太阳日就是一天 24 小时。
UTC:英文为 Coordinated Universal Time,中文叫做协调世界时或者世界标准时间,相信开发的同学都很清楚,他是世界上调节时钟和时间的主要时间标准,也是最接近格林威治标准时间 GMT 的时间系统之一。
最早的时候,一秒根据平均太阳日的 1/86400 来定义,这个时间依赖于地球的自转和公转。后来直到 1967 年,秒被物理学重新定义,以铯 133 的振荡频率来定义秒,并可以用原子钟来测量。
UTC 的时间就是基于此来定义,而且他是一个固定的时间长度。
但是由于地球自转的速度受到潮汐加速等众多因素的影响,平均太阳日的时间并不固定。
为了让 UTC 贴近平均太阳日的时间,所以就产生了闰秒。
闰秒分为两种形式:
正闰秒,也就是在 23:59:59 之后一秒是 23:59:60,然后才是 00:00:00,很奇葩很诡异是不是。
负闰秒,23:59:58 的下一秒就是 00:00:00,但是目前没有出现过负闰秒。
闰秒的时间调整一般是在 6 月 30 日或者 12 月 31 日,而离我们最近的一次闰秒的调整则是在 2016 年的 12 月 31 日。
从 1972 年到现在,已经发生了 20 多次闰秒,对于我们的系统配置来说,通过 NTP 的服务来进行时间同步,如果服务器收到闰秒的处理通知,则会一级级下发到最边缘的 NTP 服务器,然后通知到客户端的操作系统,最终由操作系统来处理闰秒。
下面的表格是历年发生闰秒的时间:
年 6 月 30 日 12 月 31 日 1972 年+1+11973 年 0+11974 年 0+11975 年 0+11976 年 0+11977 年 0+11978 年 0+11979 年 0+11981 年+101982 年+101983 年+101985 年+101987 年 0+11989 年 0+11990 年 0+11992 年+101993 年+101994 年+101995 年 0+11997 年+101998 年 0+12005 年 0+12008 年 0+12012 年+102015 年+102016 年 0+1
带来的影响
虽然闰秒对普通人的日常生活没有任何影响,但是对于开启 NTP 服务的 Linux 系统来说有致命的风险,在 Linux kernel 2.6.29 之前版本存在 bug,在进行闰秒调整时可能会引起系统导致 ntpd 进程死锁,从而导致 crash。另外由于应用程序不能处理闰秒的问题导致时间的变化,会导致 CPU load 激增。
在上一次闰秒产生,国外 Reddit、Mozilla、FourSquare、Yelp、LinkedIn 和 Gawker 都产生了一定的问题,其中 Reddit 宕机时间超过 1 个半小时。其中,或许你能很明显的看到异常错误信息:kernel[81951.244556] Clock: inserting leap second 23:59:60 UTC
另外,针对数据库方面,23:59:60
时间的问题兼容也不尽相同。
PostgreSQL:PostgreSQL 可以兼容23:59:60
的写法,不会报错。
Mysql:Mysql 还不支持 60 秒写法,闰秒时必须使用 unix time 来表示时间,否则会报错。
根据目前的信息来看,Linux 内核版本高于 2.6.29 修复了这个问题,NTP 版本高于 4.2.2p1-9 会把这一秒的时间分散到大约 2000 秒中,低于该版本的话则会直接加一秒或者减一秒。
解决方案
最简单直接的方法就是闰秒发生前停止 ntpd 服务,闰秒结束后再开启。
https://zh.wikipedia.org/wiki/%E9%97%B0%E7%A7%92
https://developer.aliyun.com/article/68260
https://yq.aliyun.com/articles/80045?spm=5176.10695662.1996646101.searchclickresult.746332ab0yvJRw
巨人的肩膀:
实际上,由于地球自转的时间无法计算,他有可能变快,也有可能变慢,受到潮汐、天气和熔态金属在地球核心的流动等各方面因素的影响,下一次闰秒的时间无法预估,但是国际地球自转和参考系服务(IERS)会提前 6 个月公布下一次闰秒的时间。
如何预测避免
UTC 阿里云时间(北京时区阿里云时间和 UTC 误差备注 2016/12/31 11:59:592016/12/31 19:59:59+0 和 UTC 完全同步 12:00:0020:00:00+012:00:01 每秒比 UTC 慢 1/86400,经过 12 小时(43200 秒)后,会比 UTC 慢 0.5 秒 20:00:01+1/8640012:00:0220:00:02+2/86400………23:59:592017/1/1 07:59:59+43199/8640023:59:60 闰秒 2017/1/1 08:00:00-0.5 秒和 UTC 误差-0.5 秒 2017/1/1 00:00:00 每秒和 UTC 误差减少 1/86400,经过 12 小时(43200 秒)后,-0.5 的误差消除 08:00:01-43199/8640000:00:0108:00:02-43198/86400………19:59:59-1/8640011:59:59……2017/1/1 12:00:002017/1/1 20:00:000 再一次和 UTC 同步 12:00:0120:00:010………
具体时间同步方案如下表格所示:
阿里云的 ECS 云服务器的 NTP 服务采用忽略闰秒时刻的跳秒,缓慢同步消除闰秒带来的 1 秒误差的方案来面对闰秒事件,实际上采用的方案是闰秒发生前,每秒比 UTC 慢 1/86400,经过 12 小时(43200 秒)后,会比 UTC 慢 0.5 秒,闰秒发生之后,每秒和 UTC 误差减少 1/86400,经过 12 小时(43200 秒)后,-0.5 的误差消除。国外 Amazon 也是这样的解决方案。
以国内阿里云的处理方案举例,amazon 同样也是采用该方案
目前像 google、阿里、amazon 都有一些具体的应对方案,使用云服务的话可能不需要用户关心这方面的问题,如果是自己机房托管的话那么可能需要运维开发人员手动处理了。
但是有一个很明显的问题就是,大公司一个服务上千台机器,操作起来成功太高,而且停止同步是否会带来其他的问题不好评估影响面。
版权声明: 本文为 InfoQ 作者【艾小仙】的原创文章。
原文链接:【http://xie.infoq.cn/article/ee3d7b0c3752674bb28e7a001】。文章转载请联系作者。
评论