服务器时间不准,看起来是小事,实际能引出一堆难查的故障。日志时间戳错乱,排查问题时对不上;分布式系统里,多台机器时间不一致会让令牌校验、数据版本、分布式锁、增量同步全部出问题;数据库主从复制、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)。所有时间跳变和写硬件时钟的操作,都要评估对业务的影响,优先在维护窗口进行。
企业QQ咨询




