一次很糙的闰秒复现
尝试写一下分享文章,主要从以下几个部分,其中第一部分多从搜索引擎中搜索总结而得,目前闰秒平滑过渡方案阿里和谷歌已经有了较为成熟的方案,并提供了公共NTP地址进行过渡。本篇旨在了解ntp和闰秒,通过几个小实验来窥探闰秒一角,在文末提供了几个链接,可做进一步参考。如果有不对的地方,欢迎各位指正。本人微信zh810216626
- 闰秒介绍
- 遇到的问题
- 处理闰秒
- 优雅的实现闰秒
闰秒介绍
闰秒是在协调世界时(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/这个网站。
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) |
遇到的问题
闰秒时,运行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’
闰秒出现:
闰秒复现:
服务A作为顶级源提供ntp服务,进行闰秒下发。在服务A
//获取最近一次闰秒,北京时间 2017.1.1 8:00
//拷贝到一个目录下
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服务器。配置如下:
Vim /etc/ntp.conf
driftfile /var/lib/ntp/drift
server 服务器A的ip
这时候等服务器A服务起来后,ntpdate 服务器A的ip,时间保持一致后,启动ntp服务
Service ntpd start
大约在八点左右即可在/var/log/message观察到闰秒已经下发的标记。
业务服务器配置:
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 里的闰秒文件
Service ntpd stop
ntptime -s 0 -f 0 //重置内核状态和频率
service ntpd start
等同步完成后服务器BC上便没有了闰秒标记。
方案二:
闰秒发生前25小时,
在服务器B
[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、wget https://hpiers.obspm.fr/eoppc/bul/bulc/ntp/sources/all_files.tar获取官方提供的校验工具
2、tar –xf all_files.tar && make clean;make
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.闰秒标记插入成功
参考资料:
转自 http://www.zengheng.top/wordpress/?p=151
感谢Herman