前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊闰秒

聊聊闰秒

原创
作者头像
hermanzeng
发布2021-12-28 20:51:10
1.2K0
发布2021-12-28 20:51:10
举报
文章被收录于专栏:herman的专栏herman的专栏

本文于2017-12-21首发于小米运维公众号,为本人原创;

本篇文章详细讲解了闰秒的出现,导致的问题以及解决方案,附带闰秒模拟实验,可供大家参考。本篇旨在较深入了解ntp和闰秒,通过几个小实验来窥探闰秒一角,在文末提供了几个链接,可做进一步参考。如果有错漏,欢迎指正。

闰秒虽然并不经常出现,但对于有很多服务器的互联网公司而言,每次都会带来各种故障,影响服务稳定性。关于闰秒平滑过渡,阿里和谷歌都已有较为成熟的方案,并提供了公共NTP地址方便大家同步。但中型以上互联网公司,还是需要有自己的内网跳秒能力,以免依赖访问外网,带来不确定性的的故障。

闰秒介绍

闰秒是在协调世界时(UTC)中增加或减少一秒,使它与平太阳时贴近所做的调整。 

1982年1月1日,国际电讯联盟(UIT)决定以UTC(协调世界时间)取代GMT,以修正由于地球在轴心上自转,故全年每天时长并不一样的世界时间。按国际惯例,UTC等同GMT,但它们的量度时间的方式不同∶ GMT从中午起量度,而UTC则由午夜起量度。UTC是法律上依据的世界时间。 UTC本身衍生自国际原子时(TAI),UTC与TAI的差距仅以整数秒计,现为32。加上闰秒的建议由国际地球自转服务提出,以确保历年来太阳平均在12:00:00 UTC至0.9秒之内经过格林尼治子午线。

上面有几个时间,看起来很晕,自己的理解。

TAI    原子时,是200台原子钟的表现时间。不会因自然环境影响。 GMT  在格林尼治子午线上的平太阳时。会因为自转等自然环境出现偏差。 UTC   叫协调世界时,起一个协调作用,综合原子时,GMT,然后各种精密计算的出来的一个时间。国内时间是UTC +8。 当这个各种精密计算出来的时间误差值超过0.9的时候,就有了闰秒。 闰秒为啥不废除争议了很久,世界无线电会议在2015年11月决议继续沿用闰秒,2023年再行商讨。这时候在提一个GPS时间,万一没有了闰秒,这个GPS时间可能就是大家的以后的时间了,这个是由GPS地面控制站和GPS本身的卫星原子钟决定的时间,在1980年一月六日的时候开始,从1980年后没有做闰秒插入处理。也就是多了18s。

图片
图片

如果没有闰秒,在N个五千年左右,就会出现凌晨十二点的日出的景象。

闰秒的信息由公布在这个网站:

https://hpiers.obspm.fr/eoppc/bul/bulc/

NTP的数据报文格式我们看一眼:

图片
图片

其中注意的一个地方是LI,闰秒标记位,二进制以及代表意义如下

00

No waring

01

Last minute of the day has 61 seconds

10

Last minute of the day has 59 seconds

11

Unknown (clock unsynchronized)

wireshark抓包看一眼:

NTP报文
NTP报文

遇到的问题

闰秒时,运行java程序的服务器load值升高,机器无法提供服务。导致上层服务不可用,间接性大规模服务可用性故障。

处理闰秒

(运行NTP or chrony的系统)

观察闰秒 通过模拟闰秒复现故障 通过重置时钟频率消除闰秒标记 通过-x方式忽略闰秒

使用软件:ntp-4.2.8p9-1.el6.x86_64 操作系统:Centos 6.3 闰秒前一天,NTP服务器会通知其客户端第二天发生闰秒。如果北京时间2018.1.1 日八点发生闰秒,则在2017.12.31 八点左右收到上一级的通知,闰秒标记位已经插入。 可以通过该命令进行检查是否对发出闰秒标记位。 [root@test tmp]# ntpq -c "lassoc" -c "mrv &1 &999 leap,srcadr,stratum"

当看到leap=01的时候,闰秒即将发生。 通过该命令验证闰秒标记位已经被设置: [root@test tmp]# ntptime |egrep 'INS|DEL'

闰秒出现(俩59):

闰秒复现:

图片
图片

服务A作为顶级源提供ntp服务,进行闰秒下发。在服务A 

代码语言:javascript
复制
//获取最近一次闰秒,北京时间 2017.1.1 8:00
Wget https://hpiers.obspm.fr/eoppc/bul/bulc/ntp/leap-seconds.list
//拷贝到一个目录下
cp leap-second.list /var/lib/ntp/leap-seconds.list
//编辑ntp配置文件
Vim /etc/ntp.conf
driftfile /var/lib/ntp/drift
restrict default kod nomodify notrap nopeer
leapfile /var/lib/ntp/leap-seconds.list
server 127.127.1.0
fudge 127.127.1.0 stratum 0
//这时候可以把时间调整到闰秒前,如果想观察闰秒前一天下发的情况可以把时间调整到2016.12.31 7:00
date -s "20161231 7:00:00"
//设置硬件时间依赖系统时间
hwclock –systohc
//启动ntp服务
service ntpd start

这时候看/var/log/message 会有一个闰秒文件加载成功的提示。 大约三到四次poll循环后即可提供服务。 服务器B和服务器C作为二级ntp服务器。配置如下:

代码语言:javascript
复制
Vim /etc/ntp.conf
driftfile /var/lib/ntp/drift
server 服务器A的ip

这时候等服务器A服务起来后,ntpdate 服务器A的ip,时间保持一致后,启动ntp服务

代码语言:javascript
复制
Service ntpd start

大约在八点左右即可在/var/log/message观察到闰秒已经下发的标记。

业务服务器配置:

代码语言:javascript
复制
Vim /etc/ntp.conf
driftfile /var/lib/ntp/drift
server 服务器B的ip
server 服务器C的ip

这时候可以等到时间2017.1.1 7:59开始观察闰秒。

这个时间比较长,要等一天。可以把整体的测试时调整到闰秒发生前半个小时进行观察。

如何清除闰秒 关于清除闰秒的两种方式,可以通过重置时钟频率在服务器A消除闰秒标记,也可以通过-x方式在服务器B和服务器C 进行忽略闰秒操作。可以根据不同的架构作出相应的调整。

方案一: 检测到闰秒标记已经下发后, 在服务器A 测试时需要注释掉/etc/ntp.conf 里的闰秒文件

代码语言:javascript
复制
Service ntpd stop
ntptime -s 0 -f 0 //重置内核状态和频率
service ntpd start

等同步完成后服务器BC上便没有了闰秒标记。

方案二:

图片
图片

闰秒发生前25小时, 在服务器B

代码语言:javascript
复制
[root@c3-cnc-lvs02-offline ~]# cat /etc/sysconfig/ntpd
# Drop root to id 'ntp:ntp' by default.
OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid -x -g" SYNC_HWCLOCK=yes

服务器A做下发闰秒操作,服务器B ntp以-x方式启动后,服务器BC均不会接受闰秒标记,大约需要33min左右完成追秒。

关于ntpd调整方式总结如下:

Offset

0-128ms

128ms-600s

600s-1000s

1000s以上

-x

慢慢调整

慢慢调整(速度大约是0.5ms/s,调整1秒要33min左右)

跳跃调整

退出(加-g参数可忽略)

不加-x

慢慢调整

跳跃调整

跳跃调整

退出(加-g参数可忽略)

优雅的模拟各种闰秒

NTPD 4.2.8版本可在ntp.conf中配置leapfile /etc/leap-seconds.list,NTPD进程会从leap-seconds.list文件中读取最近一次闰秒时间并在内核中插入闰秒标记 生成能够被NTPD进程读取和校验的leap-seconds.list文件:

1、获取官方提供的校验工具

代码语言:javascript
复制
wget https://hpiers.obspm.fr/eoppc/bul/bulc/ntp/sources/all_files.tar

2、获取最近一次的leap-seconds.list文件

代码语言:javascript
复制
tar –xf all_files.tar && make clean;make
wget https://hpiers.obspm.fr/eoppc/bul/bulc/ntp/leap-seconds.list

3、修改leap-seconds.list文件(假设在2018年1月1日凌晨0:00进行闰秒)

图片
图片

在最近一次闰秒时间后插入我们需要模拟的日期

3723753600      38      # 1 Jan 2018 修改文件中#$ 字段后的时间戳(最后一次更新该文件的日期,可不修改) 修改文件中#@字段后的时间戳(该文件的过期时间,可修改为模拟闰秒日期半年后的时间戳

4、 ./sha-leapsec < leap-seconds.list

将leap-seconds.list文件中#h 字段后的16进制hash值修改为以上标准输入的hash值,再次运行以上命令

5、闰秒文件生成成功

6、将该文件拷贝至ntp.conf配置的路径下leapfile /etc/leap-seconds.list,重启NTPD服务

7、闰秒标记插入成功

图片
图片

参考资料

https://hpiers.obspm.fr/eoppc/bul/bulc/ntp/sources/README http://www.cnblogs.com/muahao/p/6978879.html https://access.redhat.com/zh_CN/node/1422013

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • (运行NTP or chrony的系统)
  • 观察闰秒 通过模拟闰秒复现故障 通过重置时钟频率消除闰秒标记 通过-x方式忽略闰秒
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档