中文 English

电脑时间总差几百毫秒,NTP 到底在背后做了什么?从 48 字节报文到闰秒事故

发布时间: 2026-09-14 · 阅读量 --
NTP 时间同步 网络协议 运维 故障排查 Linux Windows 11 macOS 自动化 Network Time Protocol

先说结论

NTP 不是“问服务器现在几点,然后覆盖本地时间”。它更像一支带秒表的接力队:客户端记录发出和收到的时刻,服务器记录收到和发出的时刻,再用四个时间戳估算时钟偏差与网络延迟;随后在多个服务器之间做取舍、过滤抖动、处理闰秒,最后决定慢慢调频还是直接拨正。

一、为什么时间问题总是“平时没事,关键时刻爆炸”

你可能遇见过:Windows 显示未同步、Linux 却说同步成功;两台机器的日志相差几百毫秒;HTTPS 偶发证书尚未生效;域登录提示时钟偏差太大;数据库主从切换后,事件顺序像穿越。

把电脑想成学校里戴手表的孩子。老师有标准表,但传话要花时间,每个孩子的表又有快慢。NTP 就是让大家反复对表,并优先相信“传话快、历史稳定、来源可靠”的那几块表。

NTP 四时间戳

图 1:原创示意图。NTP 的核心不是一个时间,而是 T1、T2、T3、T4 四个时间。

二、一次 NTP 对话:48 字节里装了什么

NTP 通常使用 UDP 123。客户端发出请求,服务器填写自己的接收时间和发送时间,再将响应发回。四个时刻是:T1 客户端发出,T2 服务器收到,T3 服务器发出,T4 客户端收到。

offset θ = ((T2 - T1) + (T3 - T4)) / 2
delay  δ = (T4 - T1) - (T3 - T2)

offset 就是“我的表比老师快还是慢”,delay 是传话往返花了多久。这个公式假设上下行延迟大致对称;如果一边拥堵,估计就会偏。

NTP 时间戳以 1900 年为纪元,由 32 位秒数和 32 位小数组成,换算 Unix 时间要减去 1900 到 1970 的秒数。真正的误差不只来自格式,还来自网卡排队、操作系统调度、虚拟机暂停和服务器负载。

真实探针输出

图 2:真实输出。极简 Python UDP 客户端即可看到 Stratum、offset 与 delay。

NTP 字段

图 3:真实资料字段整理。Wireshark 可用 ntp 过滤报文。

三、Stratum:数字越小不一定越适合你

Stratum 0 通常是 GPS、原子钟等参考设备;直接连接它们的服务器是 Stratum 1;下游依次是 2、3……Stratum 16 表示未同步。

Stratum 层级

图 4:Stratum 更像传话层数,不是精度分数。

一个延迟小、抖动低的 Stratum 2,可能比跨洲且排队严重的 Stratum 1 更适合你。实现还会检查 root delay、root dispersion、jitter、reference ID、可达性和 leap indicator。

配置多个源时,NTP 不会简单地“三比一投票”。它先做 sanity check,再用改进的 Marzullo intersection algorithm 寻找多数时间区间的交集,排除 falseticker,最后进行 clustering 与 combining。像几位同学量黑板:先丢掉离谱读数,再相信稳定的一组。

四、clock filter:一次测量为什么不可信

网络会抖动。某次请求可能遇到 Wi-Fi 重传,offset 突然变大;下一次又恢复。NTP 通常保存最近八个样本,为样本计算延迟、偏差、dispersion 和 jitter,优先选择低延迟、低抖动的结果,而不是“最后一次说了算”。

clock filter

图 5:最近样本会按质量筛选。

五、step、slew 与 panic:最后怎么改钟

Slew 是让时钟暂时走快或走慢,像轻轻调校手表,时间连续;Step 是直接拨表,适合偏差较大但必须马上纠正的情况。传统 ntpd 常见 step threshold 约 128 ms,panic threshold 常见约 1000 秒;chrony、systemd-timesyncd、Windows Time Service 的默认值并不完全相同,请以本机实现为准。

step 与 slew

图 6:生产环境最关心的是应用会不会看到时间倒退。

六、真实 Windows 11 排查:服务运行不等于同步成功

一台 Windows 11 工作站的 w32tm /query /status 曾显示 Leap indicator: 3 (unsynchronized)Stratum: 0Source: Local CMOS Clockw32tm /stripchart 又测到约 -672 ms,并出现后续超时。要看 source、stratum、上次成功同步时间和事件日志,不能只看服务状态。

Windows 状态

图 7:真实 Windows 11 输出。

Windows 配置

图 8:真实配置输出。NtpClient 开启不代表一定选中了有效源。

stripchart

图 9:真实 stripchart 输出。一次超时是线索,连续超时才是证据。

七、Linux 与 macOS:服务名不同,排查顺序相同

Ubuntu 常见 systemd-timesyncdchrony

timedatectl status
systemctl status systemd-timesyncd --no-pager
chronyc tracking 2>/dev/null || true
chronyc sources -v 2>/dev/null || true
ss -lunp | grep ':123' || true

macOS 可用 systemsetup -getusingnetworktime 查看开关,用 sntp -sS <server> 做受控测试。三种系统都按“服务 → 源 → UDP 123 → offset/delay → 稳定性”排查,且不要让多个时间服务同时抢控制权。

Ubuntu timedatectl

图 10:真实 Linux 输出。同步成功是结果,不是完整证据。

八、闰秒:多一秒为什么能让 DNS 崩溃

UTC 偶尔插入闰秒:23:59:59 → 23:59:60 → 00:00:00。很多程序默认时间永远递增,两个时间点相减不会为负数。2012 年闰秒暴露过 Linux 相关问题;Cloudflare 的 2017 年复盘也记录了 Go 代码因负时长触发 panic。

闰秒与 leap smear

图 11:leap smear 将额外的一秒摊开,换取应用层的平滑。

这不是“谁更准确”的问题,而是取舍:科学计量可能要求严格 UTC,互联网服务则更在意不突然跳变。跨系统必须统一策略。

九、一键诊断脚本:默认只读、先 dry-run

Windows 11

$ErrorActionPreference='Continue'
Get-Service W32Time
w32tm /query /status
w32tm /query /configuration
w32tm /stripchart /computer:time.windows.com /samples:5 /dataonly
Get-WinEvent -LogName 'Microsoft-Windows-Time-Service/Operational' -MaxEvents 20

人工执行:管理员 PowerShell 运行,确认 source 后再 w32tm /resync。Agent 方法:要求 Agent 只收集 status、configuration、stripchart、事件日志,先报告,不改注册表、不重启;确认后才 resync 并提供前后证据。

Ubuntu 26.04

#!/usr/bin/env bash
set -u
timedatectl status
systemctl is-active systemd-timesyncd chrony chronyd 2>/dev/null || true
chronyc tracking 2>/dev/null || true
chronyc sources -v 2>/dev/null || true
ss -lunp | grep ':123' || true
journalctl -u systemd-timesyncd -u chrony -u chronyd -n 30 --no-pager 2>/dev/null || true

人工执行后只选择一个时间服务;Agent 方法是先识别 active daemon、输出报告,确认后再修复并复核 offset、stratum、reachability。

macOS 26

#!/bin/zsh
set -u
systemsetup -getusingnetworktime 2>&1
systemsetup -getnetworktimeserver 2>&1
sntp -S time.apple.com 2>&1 | head -20
netstat -anv -p udp | grep '\\.123 ' || true

人工确认后再执行 sudo systemsetup -setusingnetworktime on;Agent 先 dry-run,得到确认后才改设置。

参考资料

图 12:本文参考资料入口。

十、Q&A

NTP 能达到原子钟精度吗? 普通互联网 NTP 不能保证;高精度场景考虑硬件时间戳、PTP、GPS。为什么用 UDP? 丢一个测量没关系,下一轮再测;TCP 握手与重传反而会污染延迟模型。为什么测耗时要用 monotonic clock? wall clock 可能被 step,单调时钟不会倒退。只配一个源可以吗? 能跑但不抗故障,建议多个源,并监控 offset、jitter 与可达性。

参考资料

本文阅读量 --