文章作者:luxianghao
文章来源:http://www.cnblogs.com/luxianghao/p/6339470.html 转载请注明,谢谢合作。
免责声明:文章内容仅代表个人观点,如有不当,欢迎指正。
---
为什么会有闰秒?
世界上有几种计量时间的方式,
世界时(UT1):是一种天文计量的方式,天文学家通过观测地球的自转,并将自转一周的时间(一天)等分为864000份,每份为一秒,
受潮汐等因素的影响,地球自转一周的时间并不是恒定的,这也是造成闰秒现象的直接原因。
原子时(TAI):由于上面描述的世界时并不稳定,物理学家用更为稳定的量子计量的方式来统计时间,1967年,国际计量大会用铯133
(Cs133)原子基态的两个超精细能级之间的跃迁所对应辐射的9192631770个周期所持续的时间定义为1秒,这个是目前最精确的时间
计量方式,其误差为1400000年一秒,基本可忽略不计
协调世界时(UTC):又称世界标准时间或世界协调时间,UTC以TAI为基础,又要兼顾UT1,当UTC,和UT1之间的偏差接近1秒时,
国际地球自转和参考系服务(IERS)会提前6个月公布下一次闰秒的时间。
闰秒是否有规律,多长时间闰秒一次?
如下图所示,看起来并没有什么规律,如之前所说,影响地球自转的因素没什么规律,那么闰秒自然也没什么规律。
闰秒有什么影响?
对于普通人来说,正常的上班、下班、工作、学习,生命中偏差的这一秒无关痛痒,这个倒不会像闰年,闰月那样,影响人的生日
对于对时间要求比较精确的航空、航天、军工等,影响就会比较大了
对于我所在的互联网行业,服务器清一色的linux系统,闰秒可能会造成机器cpu突然增高,机器宕机等,对应的服务就会挂掉,
因为互联网是最近几年才蓬勃发展起来,所以之前的闰秒对linux的影响就没被放大,随着linux的普遍使用,闰秒也被越来越多的被关注。
闰秒对linux以及在linux上run的应用的影响
系统打印闰秒插入信息的时候夯住:当NTP通知内核关于闰秒的动作时,这个bug会被触发,这个bug会发生在闰秒发生的前一天的任何时候,
这个bug提前被触发的原因是NTP时间服务器会提前一天通知连接它的linux服务器,将来的某个时刻会发生闰秒,linux服务器的ntp收到这个信息
后会在闰秒时刻对linux的时间做一些处理,增加一秒,或者减去一秒
闰秒活锁导致系统夯住:由于这个bug,NMI看门狗会检测到系统夯住,系统会不停的crash;闰秒被插入后这个bug就会被触发,目前还没确定
哪个版本修复了这个bug
cpu load快速增高:其原因为应用程序不能处理闰秒带来的系统时间的突然变化,linux系统提供两种系统时间,wall time和montonic time,其中
wall time记录的是事实时间,可以向前或者向后调整,montonic time记录的是系统从启动以来的秒数,只能向前递增,因此如果应用程序在获取时间
时用的wall time则会受到系统时间调整(如闰秒)的影响,而采用后者则不会受到影响,具体到jdk来说明在jdk 7u6开始采用后者。
不能处理闰秒的内核在处理闰秒发生故障时会有什么样的系统日志
eg: Kernel panic - not syncing: Watchdog detected hard LOCK UP on cpu 21
闰秒后系统日志会有什么记录?
eg: kernel[81951.244556] Clock: inserting leap second 23:59:60 UTC
内核bug修复情况
以上提到的bug在linux各个版本陆陆续续有修复,这里提供一个安全的版本,内核是2.6.39-200.3或者更高版本的可以认为是安全的
ntp && 闰秒
主机使用了ntp
此时主机在闰秒时的表现将取决于使用的ntp的版本
1 版本高于等于4.2.2p1-9 或者更高版本(除了ntp-4.2.6p5-19.el7, ntp-4.2.6p5-1.el6 and ntp-4.2.6p5-2.el6_6)
a 带-x参数运行:闰秒不是直接在内核中添加,而是把这一秒分散到大约2000秒中,1秒比之前长一些,缓慢的更改时间,
这样做的优点:
1)避免时间倒退造成的应用逻辑问题
2)比较奇怪的时间点23:59:60不会出现
3)由于实际上没有增加闰秒,所以上面描述的内核bug也不会出现
这样做的缺点:
1)由于调整的时间段内,一秒的长短实际上是不准确的,所以对时间精度要求高的场景就不适用了
2)由于ntp的更新机制,这个办法同样也不适用于那些要求所有节点时间一致的集群
b 不带-x参数运行,ntp会通知内核直接增加一秒(是突增的,非连续的)
2 版本低于4.2.2p1-9
ntp会通知内核直接增加一秒,或者在停止一秒
注意:如果主机上运行了ntp,那么运行“file /etc/localtime”,确保输出结果中有“no leap seconds”(这表明不会添加闰秒)
主机没有使用ntp
1 没有使用tzdata
那么主机的时间完全由自己调整,建议使用ntp加上-x参数
2 使用了tzdata
a 版本低于2015a,不会添加闰秒
b 大于等于2015a,并且运行“file /etc/localtime”,输出结果中有“X leap seconds”(X是个数字)
那么闰秒会以“23:59:60”这样的形式出现,这会导致DATE/TIMESTAMP数据类型出现问题,
你需要复制适当的/usr/share/zoneinfo文件覆盖/etc/localtime(这个操作是动态调整的,不需要重启)
应对闰秒的总结
1 升级内核使版本大于等于2.6.39-200.3,内核能够处理闰秒,但是依然要提防应用程序对时间的敏感度,具体情况可参考这个,
针对这样的应用程序,你需要
a 重构代码
b 升级对应的软件如jdk
2 在主机是任何版本内核的情况下,升级ntp是版本大于等于4.2.2p1-9,来应对那些对时间精度要求不高的场景
3 对于那些既不关心时间精度,也不想升级任何东西的,那就重启ntp
a 在上级时间服务器发闰秒通知开始之前停止ntp(需提前一天 /etc/init.d/ntpd stop),
b date -s "`date`" (重置系统时间,个人认为这样做可能是为了解开闰秒造成的死锁)
c 启动ntp/etc/init.d/ntpd start
4 copy时间文件应对tzdata添加的闰秒