共计 3571 个字符,预计需要花费 9 分钟才能阅读完成。
导读 | ntpd 是一个操作系统 Daemon 进程,用于校正本地系统与 Internet 标准时钟源之间的时间。ntpd 完整的实现了 NTP 协议版本 v4,但是同时兼容版本 v3(RFC-1305)、版本 v1 与 v2(分别由 RFC-1059, RFC-1119 定义)。ntpd 绝大多数情况下使用 64 位浮点数计算,仅在需要极高时间精度的情况下使用笨拙的 64 位固定长度数计算,这个极高的精度是 232*1/1,000,000,000,000 秒;要达到这个精度对 CPU 与网络带宽的要求已超过 GHZ 与 GMbps 的级别,当前的大多数工作站都无法满足。 |
ntpd 进程通过定期与 NTP 时钟源服务器发送消息来获取时间信息。在进程初始启动时候,不论是第一次 boot 还是随后启动,nptd 会给服务器发送消息以获取时间本设置到本地系统。为了防止网络风暴,进程启动后会在定义好的间隔 64 秒之上再加一个随机延迟值,这个随机值的范围是 0~16 秒;因此进程启动后需要数分钟才会开始同步时间。
如今的计算机都带有硬件时钟芯片 (time-of-year (TOY) chip),用于在计算机掉电过程中仍然保持正确时间,当计算机上电,操作系统从时钟芯片中获取时间。当操作系统启动完成并连接到时钟源之后,操作系统会依据时钟源定时调整芯片时间。 在服务器没有硬件时钟芯片或硬件时钟芯片故障(CMOS 电池没电)或其他原因导致操作系统本地时间与时钟源时间差别超过 1000 秒,nptd 认为此时发生了严重问题,唯一可靠的处理方法是人为介入。这种情况下 nptd Daemon 进程会退出并在操作系统的 syslog 中记录一条日志。nptd 的启动选项 -g 选项可以忽略 1000 秒的检查并强制将时钟源时间设置为硬件时间,不过考虑到硬件时钟芯片故障的场景(CMOS 电池没电、或时钟计时器故障),一旦再次出现芯片时间与时钟源超过 1000 秒,nptd 还是会退出。
通常情况下,ntpd 以很小的步长调整时间使得时间尽量是连续的、不出现跳跃。在网络极度拥塞的条件下,nptd 与时钟源之间发送一个消息包来回的时延有可能达到 3 秒,因此会导致同步距离(半个来回时延,1.5 秒)变的很大。ntpd 同步算法会丢弃时差大于 128ms 的包,除非在 900 秒内没有时差小于 128ms 的包,还有就是首次启动时候不会检查这个时差直接同步。这种设计是为了减少误报时钟同步异常的告警。
上述行为的结果是每次成功设置本地时间,一般不会超过 128ms,即使在网络时延很高的情况下。有时候,特别是在 ntpd 首次启动的时候,时差可能超过 128ms,这种罕见场景一般是本地时间比时钟源的时间快(未来)超过 128 秒,这种情况本地时间将会被往过去方向调回。这种情况下某些应用程序会有问题。如果启动 nptd 时候加上了 -x 选项,那么 nptd 不会以步长方式 (stepped) 同步,只会以微调校正方式 (slew correction) 同步。
使用 -x 选项之前需要仔细考量影响。ntpd 微调校准的最大频率是 500 个 PPM (parts-p
er-million)每秒,也就是每秒校准 5/10,000 秒。因此会导致本地时间与时钟源之间需要很长时间才能将时差同步到一个可接受的范围,大概是 2000 秒同步一秒,对于依赖网络时钟源的应用来说这种情况不可接受。
nptd 启动时的行为依赖频度文件是否存在,通常是 npt.drift。这个文件包含了最近估算出的时钟频度误差值。如果文件不存在,此时 ntpd 进入一种特殊模式会快速调整时间与频度误差值,这个快速大概好事 15 分钟,随后在时间与频度误差值正常后 nptd 进入正常模式,时间与频度持续与时钟源同步。并在一个小时之后,将当前的频度误差值写入 npt.drift 文件。如果文件存在,nptd 从此文件读取频度误差值直接进入正常模式,并没隔一个小时将计算好的频度误差值写入文件。
nptd 可以运行在多种模式下,包括对称的 主动、被动(active/passive),客户端、服务端(client/server),广播、多播(broadcast/multicase/manycase),详细参考 Association Management。通常运行模式是以 Daemon 方式持续跟踪同步时钟源时间;当然也可以只运行一次,从外部时钟源同步时间(从上次纪录的频度误差文件中读取频度误差值)。广播与多播模式下客户端能够自动发现时钟源服务器,并计算各个服务器的时延然后自动完成配置,这种模式使得工作站集群自动配置变为现实。
默认情况下 nptd 以 Daemon 方式持续跟踪多个时钟源,同步的间隔由一个复杂的状态机决定。状态机使用启发式算法,根据消息包来回时延、频度误差来计算最优的同步间隔。通常情况下,状态机初始以 64 秒为间隔并最终达到 1024 秒,少量的随机数值会被增加到间隔上为了均衡服务器压力。额外的,如果一个服务器不可达的情况下,为了减少网络消息排队阻塞,间隔会逐步增加到 1024 秒。
在某些情况下 nptd 不能正常持续运行,通常的规避手段时使用 cron 定时任务执行 ntpdate 命令。但是 ntpdate 并没有像 nptd 一样有考虑各种信号处理、错误检查、连续同步算法。nptd -q
可以达到与 ntpdate 同样的效果,-q
参数使得 npt 同步一次后就退出;同步的过程与 Daemon 模式的 nptd 是相同的。
如果操作系统内核支持调整时钟频度(Solaris,Linux,FreeBSD 都已经支持),那么时钟同步还有一种不以 Daemon 方式运行的可选用法。首先,nptd 以 Daemon 方式运行,配置好时钟源,大约一个或几个小时后,获取到频度误差 npt.drift 文件;然后退出 nptd 进程,并以一次性模式运行(nptd -q
),此时每次 nptd 运行都基于当前获取到的频度误差与时钟源同步时间。
当前版本的 NTP 包含了一个复杂的状态机,用于减少同步时的网络负载;同时也包含很多种提升精度的方法。使用者在修改同步间隔(64 秒~1024 秒)的时候需要仔细考虑影响。默认的最小同步间隔可以使用 tinker minpool 命令修改为不小于 16 秒,这个值会被用作所有相关的使用到同步间隔的地方,除非显示使用 minpoll 选项覆盖。需要注意的是不少设备驱动在同步间隔小于 64 秒时候不能正常工作;同时广播与多播模式也是使用的默认值,除非显示覆盖。
-d
efault'>ntpd [-d
efault'>-aAbdgLmNPqx ] [-c conffile] [-f driftfile] [-g] [-k keyfile] [-l logfile] [-N high] [-p
pidfile ] [-r broadcastdelay] [-s statsdir] [-t key] [-v variable] [-V variable] [-x]
命令行参数
-d
efault'>-a
“md_block md_has_block_below md_has_block_below_ul”>– -A
-d
efault'>-b
– -c conffile
-d
– -D level
-f driftfile
– -g
-k keyfile
– -l logfile
-L
– -m
-n
– -N priority
-p
– -P
-q
– -r broadcastdelay
-s statsdir
– -t key
-v, -V
– -x