服务器时间不准确怎么办?NTP时间同步配置与故障排查

服务器时间不准,看起来是小事,实际能引出一堆难查的故障。日志时间戳错乱,排查问题时对不上;分布式系统里,多台机器时间不一致会让令牌校验、数据版本、分布式锁、增量同步全部出问题;数据库主从复制、TLS 证书校验、短信验证码有效期、订单超时,都依赖准确的时间。更麻烦的是,时间跑偏往往是"悄悄发生"的——业务不会立刻报错,而是过一段时间以各种诡异的方式暴露。

这篇文章讲清楚服务器时间同步这件事:NTP(网络时间协议)和 chrony/ntpd 两套工具的区别、怎么配置时间源、怎么用 timedatectl 和 chronyc 看状态、防火墙要怎么放行、以及最常见的几个坑(时钟偏差太大直接同步不上去、虚拟机时间漂移、硬件时钟没同步)。读完你应该能给一台新服务器配好可靠的时间同步,也能在时间跑偏时快速定位原因。

一、先分清时间相关的三个概念

排查时间问题前,先把三个容易混的东西分开:

  • 系统时钟(system clock):内核维护的当前时间,date 看到的就是它。系统运行期间以它为基准。
  • 硬件时钟(RTC,real-time clock):主板上的 CMOS 电池供电的时钟,关机后继续走。开机时用它初始化系统时钟。
  • 时区(timezone):只是"显示规则",把 UTC 时间换成某个地区的本地时间。时区配错会让人觉得"时间不对",但其实 UTC 是对的。

所以"时间不准"可能是三件事之一:系统时钟跑偏了、硬件时钟错了、或者只是时区配错了。排查时先分清。

# 看当前时间、时区、NTP 同步状态
timedatectl

# 看系统时钟与硬件时钟的差异
timedatectl
date
hwclock --show          # 看硬件时钟(root)

timedatectl 的输出里几个关键点:

               Local time: ...
           Universal time: ...          # UTC 时间
                 RTC time: ...
                Time zone: Asia/Shanghai (CST, +0800)   # 时区对不对看这里
System clock synchronized: yes              # 是否已同步
              NTP service: active           # NTP 服务是否在跑
          RTC in local TZ: no               # 硬件时钟存储的是 UTC 还是本地时间

如果 System clock synchronized: no,说明系统时钟没有和任何时间源同步,很可能已经跑偏。

二、chrony 和 ntpd 怎么选

Linux 上做时间同步主流有两套:老的 ntpd 和现代的 chrony。现在主流发行版(RHEL/CentOS 7+、Rocky、新版本 Ubuntu/Debian)默认用 chrony。

对比项 chrony ntpd
现状 现代主流,默认安装 传统,逐步被替代
客户端/服务端 chronyd / chronyc ntpd / ntpq、ntpdate
同步速度 快,启动后较快收敛 慢,逐步微调
网络适应性 好,适合时断时续、虚拟机 差,长期离线后同步慢
对时钟偏差大 能较快校正(makestep) 偏差太大时不接受,需手工干预
虚拟机场景 推荐 不推荐
配置文件 /etc/chrony.conf /etc/ntp.conf

结论:新部署统一用 chrony,除非有历史包袱。下面以 chrony 为主,同时给出 ntpd 的对应做法。

三、chrony 配置与状态查看

安装

# RHEL/CentOS/Rocky
sudo dnf install -y chrony        # 老版本用 yum
sudo systemctl enable --now chronyd

# Debian/Ubuntu
sudo apt update && sudo apt install -y chrony
sudo systemctl enable --now chrony     # Debian/Ubuntu 服务名是 chrony,不是 chronyd

注意服务名差异:RHEL 系是 chronyd,Debian/Ubuntu 是 chrony。别搞混。

配置时间源

编辑 /etc/chrony.conf,核心是 server(或 pool)行。下面这些公共 NTP 源仅作示例,实际请以各服务商官方文档为准,企业内网应优先使用自建或供应商提供的源:

# 示例:使用公共 NTP 源
# 阿里云公共 NTP(以官方文档为准)
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst

# 腾讯云公共 NTP(以官方文档为准)
server ntp.tencent.com iburst

# 国家授时中心(以官方文档为准)
server ntp.ntsc.ac.cn iburst

# pool 会自动解析多个地址
pool pool.ntp.org iburst

# 允许本地网络客户端来同步(把本机当时间服务器时用)
# allow 192.168.1.0/24

# 本地时钟兜底:当所有外部源不可达时,用本机时钟继续服务
# 注意:这只在无法联网的内网时间服务器上才用,且要配合 allow
# local stratum 10

# 允许启动时快速校正偏差(见下方说明)
makestep 1.0 3

# 使用硬件时钟作为时间源之一(虚拟机、无网络时有用)
# 一般 rtcfile 已默认启用

参数说明:

  • iburst:启动时快速发送多个包以快速收敛,强烈建议加。
  • pool:域名解析出多个 IP,chrony 自动选择。适合公网源。
  • makestep 1.0 3:如果时间偏差超过 1 秒,前 3 次同步允许"跳变"(step)而不是慢慢微调。这对时钟偏差太大的场景很关键(默认 chrony 是缓慢 slewing,偏差很大时收敛很慢)。
  • local stratum 10:让本机在没有外部源时仍能作为时钟源对外服务,适合内网隔离环境。配置不当会导致错误时间传播,仅限受控场景使用。

改完重启并检查:

sudo systemctl restart chronyd        # Debian/Ubuntu: chrony
chronyc sources -v                    # 看时间源列表
chronyc sourcestats -v                # 看统计
chronyc tracking                      # 看同步状态
timedatectl                           # 确认 synchronized: yes

怎么读这些命令的输出

chronyc sources -v:列出所有配置的时间源。每行前面的符号:

符号 含义
* 当前选中的同步源(正在用这个)
+ 备选源,质量不错但没被选中
- 被排除的源
? 不可达或未通过校验
x 被认为是错误源(falseticker)

如果所有行的状态都是 ?,说明一个源都没连上,通常是被防火墙挡了或者网络不通。

chronyc tracking:看同步质量。重点字段:

Reference ID    : ...              # 当前参考源
Stratum         : 3                # 层级,越小越接近权威时钟
System time     : 0.000012345 seconds slow of ...   # 系统时钟偏差
Last offset     : ...
RMS offset      : ...              # 均方根偏差
Leap status     : Normal

System time 接近 0 表示同步良好;如果显示偏差很大(比如几秒、几分钟),说明还没收敛或源不准。

chronyc ntpdata <地址>:看与该源的 NTP 包交互细节(偏移、延迟、抖动、版本等)。

chronyc ntpdata 203.0.113.10
chronyc sources -a          # 显示更多源(含不可达的)
chronyc activity            # 看源数量概况

四、ntpd 的对应用法

如果用的是 ntpd:

# RHEL/CentOS/Rocky
sudo dnf install -y ntp
sudo systemctl enable --now ntpd

# Debian/Ubuntu
sudo apt install -y ntp
sudo systemctl enable --now ntp      # 服务名是 ntp

# 配置文件 /etc/ntp.conf,同样用 server / pool 行
# 查看同步状态
ntpq -p        # 列出对等源,* 表示当前源
ntpq -c rv     # 汇总
ntpstat        # 是否已同步(Debian/Ubuntu)

# 一次性强制同步(ntpdate,注意:现在很多系统已弃用)
# 仅在 ntpd 未运行时用 ntpdate 手校;chrony 用 chronyc makestep
sudo ntpdate ntp.aliyun.com

注意:ntpd 对"时钟偏差太大"很不友好,偏差超过约 1000 秒(panic 阈值)它可能拒绝同步,需要先用 ntpdate 或 date -s 手动把时间调接近,再让 ntpd 接管。

五、时区与硬件时钟

设置时区

# 列出时区
timedatectl list-timezones | grep -i shanghai

# 设置时区(中国用 Asia/Shanghai)
sudo timedatectl set-timezone Asia/Shanghai

# 老系统没有 timedatectl 时,直接改软链接
sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

硬件时钟的 UTC/本地时间

Linux 惯例是硬件时钟存 UTC,系统按需转换。如果双系统(Windows 会把 RTC 当本地时间)或多系统共存,容易冲突。

# 看当前设置
timedatectl | grep 'RTC in local TZ'

# 让硬件时钟使用 UTC(推荐)
sudo timedatectl set-local-rtc 0

# 若要与 Windows 共存,可能设为 1(硬件时钟按本地时间)
sudo timedatectl set-local-rtc 1

# 把当前系统时间写入硬件时钟(系统时间正确后执行)
sudo hwclock --systohc          # 或 hwclock -w
# 反过来,用硬件时钟校准系统时间(系统没网时)
sudo hwclock --hctosys          # 或 hwclock -s

风险提示:hwclock --systohc 会用(可能还不对的)系统时间覆盖硬件时钟。执行前务必确认系统时间已经正确(先同步 NTP)。顺序是:先让 NTP 校准系统时钟 → 再写入硬件时钟。

六、防火墙:放行 NTP

NTP 用的是 UDP 123 端口。如果源连不上(chronyc sources 全是 ?),八成是防火墙或安全组的问题。

# 本机作为 NTP 客户端时,出站一般不限,出站 UDP 123 通即可
# 客户端不需要专门开防火墙;但如果本机也是 NTP 服务器(对外提供时间),要放行入站 UDP 123

# RHEL/CentOS/Rocky:firewalld 放行 NTP
sudo firewall-cmd --permanent --add-service=ntp     # 或 --add-port=123/udp
sudo firewall-cmd --reload
sudo firewall-cmd --list-services | grep ntp

# Debian/Ubuntu:ufw 放行 NTP
sudo ufw allow 123/udp
sudo ufw status

# 云服务器还要检查:安全组是否放行 UDP 123(入站,若对外服务)

排查客户端连不上源时,先用 nc 或 ntpdate -q 测一下:

# 测 UDP 123 是否可达(UDP 用 nc 测不准,可用 ntpdate 查询模式)
ntpdate -q ntp.aliyun.com
# 或直接用 chronyc 看源状态
chronyc sources -v

七、常见问题与排查

1. 时钟偏差太大,同步不上

这是最典型的问题。服务器离线很久,或虚拟机被挂起很久,时间偏差可能到了几小时甚至几天,超过 NTP 的校正范围。

chrony 的处理:默认是缓慢 slewing(微调),偏差大时会很慢。解决方式是配置 makestep 1.0 3,让它在启动阶段直接跳变;或手动强制:

# 方法一:配置 makestep 后重启
# /etc/chrony.conf 加:makestep 1.0 3
sudo systemctl restart chronyd

# 方法二:手动强制一步到位(chrony 3.2+)
sudo chronyc makestep
chronyc tracking

ntpd 的处理:先用 ntpdate 手校到接近,systemctl start ntpd 接管。

风险提示:时间跳变会影响正在运行的业务(如基于时间的调度、证书校验、数据库事务)。生产环境尽量在业务低峰或在维护窗口同步,并优先保证是"同步到正确时间"而非反复跳。

2. 虚拟机时间漂移

虚拟机时间容易漂移,原因是 CPU 被宿主机抢占、时钟中断不稳定,虚机"感觉不到"真实流逝的时间。表现是虚机时间跑慢或跳变。

解决思路:

  • 开启虚拟化平台的时间同步功能(如 VMware Tools 的时间同步、KVM 的 kvm-clock 时钟源)。
  • 虚机内仍配置 chrony 作为主,平台工具可作辅。
  • 检查虚机时钟源:cat /sys/devices/system/clocksource/clocksource0/current_clocksource,KVM 下应为 kvm-clock。
  • 避免"平台同步"和"chrony"同时大幅纠偏导致来回打架,配置上让平台只做小范围校正。

3. 时间同步了但重启后又不准

说明硬件时钟没同步,或 NTP 服务没设开机自启。

# 确认 NTP 服务开机自启
systemctl is-enabled chronyd      # 应为 enabled
systemctl enable chronyd

# 把正确时间写入硬件时钟
sudo hwclock --systohc

4. NTP 服务在跑但没同步

# 看服务状态和日志
systemctl status chronyd
journalctl -u chronyd -n 50 --no-pager

# 看源状态,是否都是 ?
chronyc sources -v
# 检查网络、防火墙 UDP 123

5. 时间被别的进程改回去了

有时是虚拟化平台工具(VMware Tools / Hyper-V 集成服务)在后台同步,覆盖了 chrony。二者选其一为主,或在平台侧调小同步频率。

常见问题

Q:timedatectl 显示 System clock synchronized: no,但时间看着是对的,要紧吗?
要紧。手动看着对不代表持续准确,系统时钟会随硬件温漂慢慢跑偏。应让 NTP 服务接管,确保 synchronized: yes。

Q:chronyc sources 里全是 ?,怎么查?
说明所有源都不可达或校验失败。依次检查:网络是否通(能否 ping 通源的域名)、DNS 是否正常、防火墙/安全组是否放行 UDP 123、源地址是否写对。用 chronyc sources -v 看 Reach 列,非 0 表示有过响应。

Q:偏差几分钟,chronyc 半天不同步,怎么办?
检查是否配了 makestep 1.0 3。没配的话 chrony 默认缓慢微调,偏差大时很慢。加上这行重启,或执行 sudo chronyc makestep 强制跳变(注意业务影响)。

Q:服务器时间对,但应用日志时间不对,为什么?
多半是应用自己用了错误的时区(如 JVM 的 user.timezone、PHP 的 date.timezone、容器的 TZ 环境变量)。检查应用/容器时区设置,与系统时区保持一致。

Q:内网服务器不能访问公网 NTP,怎么办?
搭建一台能访问公网的机器做内网时间服务器(chrony 配 allow 内网网段,可选 local stratum 10),其他机器指向它。注意 local 的时钟源可信度低,仅在无法获得外部源时使用。

总结

时间不准的排查,先分清三件事:系统时钟、硬件时钟、时区。用 timedatectl 一眼看清状态,date、hwclock --show 辅助确认。

新部署统一用 chrony:装 chrony(RHEL 系服务名 chronyd,Debian 系 chrony),在 /etc/chrony.conf 配 server(加 iburst),配上 makestep 1.0 3,重启后用 chronyc sources -v 和 chronyc tracking 验证。ntpd 用户对应 ntpq -p、ntpstat。

防火墙要放行 UDP 123(对外提供时间服务时必须);内网可自建时间服务器。

最常见的坑是:时钟偏差太大同步不上(用 makestep 强制)、虚拟机时间漂移(开平台时钟同步 + kvm-clock)、硬件时钟没同步(hwclock --systohc)。所有时间跳变和写硬件时钟的操作,都要评估对业务的影响,优先在维护窗口进行。