我正在开发一个 C 应用程序,需要在主机上同步 NTP 时间,然后才能继续。我基本上编写了一个执行命令的包装 C 函数ntpq -p
如果输出包含 * 字符,我认为已连接并准备好继续。 NTP 成功同步的示例输出:
remote refid st t when poll reach delay offset jitter
==============================================================================
*myserver.domain.com xxx.xxx.xxx.xxx 2 u 729 1024 377 1.120 -1.834 2.282
如果输出才不是包含 * 字符,我的程序会休眠一秒钟,然后再次检查。重复此过程直到找到 * 字符。
然而,我注意到在我的一台机器上,* 字符在重新启动后需要很长时间才能最终显示(约 5 分钟)。但它似乎已经更快地成功同步了。换句话说,当我发出 a 时datetime
,它显示了一个看似正确的时间,该时间必须是从 NTP 服务器获取的,但 * 字符直到几分钟后才出现。
这会对我的应用程序产生负面影响,因为它在系统重新启动后基本上无法运行 5 分钟。
我在 ntp.conf 文件中使用“iburst”选项,希望它能够快速同步。
# my NTP server config
server myserver.domain.com iburst
同样,它似乎同步得很快,但ntp -q
输出需要一段时间才能报告 * 字符。
关于如何解决此行为有什么想法吗?另外 - 是否有更好的命令来检查 NTP 同步是否已完成?
编辑#1:添加更多信息
我从 Chris Davies 的回复中了解到,ntpd 需要 8 次成功的轮询才能被视为同步。这解释了为什么我的时钟看起来是正确的,尽管它没有同步。没有意义的是为什么它在启动时的轮询如此缓慢,即使我设置了 iburst 选项。
我注意到 refid = .STEP。在初始启动时。我不确定这是否相关,因为这只是意味着初始同步非常大。
编辑#2:这是完整的序列
主机启动 - 似乎发生了初始 NTP 同步并且更改非常大,因此 refid = .STEP。
一段时间后,refid 更新了我的 NTP 服务器的 IP 地址。然而,它仍然被认为是不同步的,因为没有发生连续8次成功。而且它仅每 64 秒轮询一次,因此同步时间较长。注意:我确实启用了 IBURST!
如果我重新启动 NTP 守护程序服务,它会立即恢复并同步。好像 iburst 现在工作正常。
当 NTP 守护进程在重新启动后启动时,这几乎就像 iburst 选项失败一样。但是如果重新启动服务就可以正常工作。
答案1
您的系统使用 initramfs 吗?如果有的话,修改后更新了吗ntp.conf
?如果没有,系统可能会在启动过程的早期使用initramfs 中存储的ntpd
旧版本启动...这可能解释了为什么该选项在启动时似乎被忽略。ntp.conf
iburst
重新启动时ntpd
,将使用最新版本的ntp.conf
,因此该iburst
选项将被采用。
如果初始同步总是导致非常大的变化(refid = .STEP.
正如您所说),请查看您的发行版是否允许您ntpdate
在启动之前在启动时运行ntpd
。这个想法是,ntpdate
将处理大的步骤,然后从ntpd
已经非常接近正确时间的系统时钟开始,理想情况下允许iburst
在不改变步骤的情况下成功。
答案2
NTP 客户端不会认为自己已同步,直到其服务器Reachable
值为377
。这是一个八位移位寄存器,并且在每个周期,指示远程服务器是否可达的Poll
值0
或值被移入最低位。1
八进制值377
表示11111111
(连续八次成功读取远程服务器)。
发生这种情况时,您将*
在选定的“truechimer”(提供合理时间的服务器)旁边看到一个,以及+
其他也完全可访问但当前未选择的“truechimer”旁边。
理想情况下,您应该拥有奇数个远程 NTP 服务器,并且不止一个。三是一个很好的数字,对于我使用池服务器来说,它们可能如下所示:
0.pool.ntp.org
1.pool.ntp.org
2.pool.ntp.org