当前位置:首页>Linux>Linux 服务器时间同步(NTP/chrony)最佳实践

Linux 服务器时间同步(NTP/chrony)最佳实践

  • 2026-06-28 09:40:07
Linux 服务器时间同步(NTP/chrony)最佳实践

问题背景

时间同步是 Linux 运维里最容易被忽视、但一翻车就坑死一票业务的基础设施。生产里这些抱怨几乎每周都能听到:

  • 业务方反馈"日志时间戳跟实际对不上",排查事故时复盘会议直接卡在第一步。
  • K8s 集群里 kube-apiserver 报错 x509: certificate has expired or is not yet valid,节点时间漂移几小时,证书根本没过期。
  • MySQL 主从复制 Seconds_Behind_Master 忽大忽小,磁盘和锁都正常,最后发现从库时间比主库快 5 秒。
  • 凌晨跑批任务,crontab 莫名其妙没触发,第二天才发现服务器时间比现实时间慢了 6 小时。
  • 同一台机器里 date 和 hwclock 输出的时间差了好几小时,重启后一切又变回来。
  • 容器里 date 显示的是宿主机时间,但 clock_gettime(CLOCK_MONOTONIC) 跟宿主机不一致,部分用 monotonic clock 做逻辑的中间件直接行为异常。
  • 等保 2.0 测评报告里被写了一条"未配置可信时间源",要求限期整改。
  • 双十一凌晨运维登录堡垒机,被强制下线,提示"登录时间异常"。

这些故障的根因几乎都指向一件事:服务器时间不可信。Linux 服务器的时间其实是一个由"硬件时钟(RTC)+ 内核维护的 system time + NTP 守护进程 + 时区配置 + 闰秒/跳秒策略"共同协作的小系统。任何一个环节没配好,都会出现上述现象。

这篇文章面向初中级运维 / 系统管理员 / DevOps 工程师,从原理到实战,把 chrony 这条主线讲透,覆盖单机、云服务器、容器、K8s 节点、自建 NTP 服务器、内网隔离等场景。看完之后能独立完成时间同步选型、配置、排查和合规落地。

适用读者

  • 维护 Linux 服务器集群(物理机、虚拟机、云服务器、容器节点)的运维工程师。
  • 排查过"时间跳变、日志错乱、证书校验失败、数据库主从延迟、K8s 节点 NotReady"问题的同学。
  • 准备做等保 2.0、PCI-DSS、ISO 27001 等合规加固的工程师。
  • 想从 ntpd 迁移到 chrony 或反过来评估的工程师。
  • 想自建内网 NTP 服务器、减少对公网依赖的平台工程师。

适用场景

  • 物理服务器、VMware 虚拟机、KVM 虚拟机、Hyper-V 虚拟机。
  • 阿里云、腾讯云、华为云、AWS、Azure、GCP 等公有云 ECS / VM。
  • 私有云、混合云、隔离网络。
  • Docker 宿主、K8s node、K3s edge 节点。
  • 自建 NTP 服务器(stratum-1 / stratum-2)。
  • 金融、政企、医院、制造业等强合规行业。
  • 数据库(MySQL、PostgreSQL、Redis、MongoDB)主从复制、分布式一致性场景。
  • 分布式存储(HDFS、Ceph、MinIO)集群。
  • 消息队列(Kafka、RocketMQ、RabbitMQ)集群。
  • 证书体系(PKI、TLS、Kerberos、LDAP)环境。

核心知识点

时间的几个概念

系统时间(System Time / Software Clock)

由 Linux 内核维护的墙上时钟(wall clock),单位是自 1970-01-01 00:00:00 UTC 起的秒数 + 纳秒部分。所有 dategettimeofdaytime()clock_gettime(CLOCK_REALTIME) 都读这个值。

系统时间由内核 tick 或 tickless 模式维护,本身没有"绝对意义",完全靠 NTP/chrony 这种用户态守护进程不断校准。系统时间可以"跳变"(slewing 太慢时直接 settimeofday 改掉),但单调时钟不能跳变。

硬件时间(Hardware Clock / RTC)

主板上由电池供电的小芯片保存的时间,机器断电后依然走时。Linux 里通过 /dev/rtc0 访问,可以用 hwclock 命令读写。

  • UTC 模式:硬件时间保存为 UTC,开机后操作系统按时区计算本地时间。推荐,跨时区服务器、集群、云服务器都应该用 UTC 模式。
  • local 模式:硬件时间保存为本地时间,跨时区会错乱。除非有遗留系统对接 Windows 双系统遗留配置,否则不要用 local 模式。

可以用 timedatectl 查看 RTC in local TZ: no 确认。

单调时钟(CLOCK_MONOTONIC / CLOCK_BOOTTIME)

Linux 内核另一个时钟源,从某个未指定的起点开始单调递增,NTP 不会调整它。应用如果做超时、心跳、限流,应该用 monotonic clock,否则系统时间跳变(NTP 第一次同步时强制 step)会导致逻辑全乱。

clock_gettime(CLOCK_MONOTONIC, &ts) 是关键 API。K8s、etcd、RocksDB、LevelDB、Tokio 运行时、Rust 标准库等都依赖 monotonic clock。

UTC、本地时间、时区

  • UTC(Coordinated Universal Time):世界统一时间,NTP 协议传递的就是 UTC。
  • 本地时间(Local Time):UTC + 当前时区偏移 + 夏令时调整。
  • 时区(Timezone):存放在 /etc/localtime(通常是 /usr/share/zoneinfo/<区域>/<城市> 的软链),可以用 timedatectl set-timezone Asia/Shanghai 改。

容器内 /etc/localtime 默认继承宿主,但 Pod spec 可以通过 volumeMounts 单独挂载。

NTP 协议基础

NTP(Network Time Protocol,RFC 5905)是 Linux 时间同步的事实标准协议,使用 UDP 123 端口。chrony 和 ntpd 都遵循这个协议,但实现上有差异。

几个关键术语

  • stratum(层):时钟源距离"权威时钟源"的跳数。stratum-0 是原子钟、GPS 接收机这种硬件参考源;stratum-1 是直接连 stratum-0 设备的服务器;stratum-2 是从 stratum-1 同步的服务器,依此类推。stratum 越大误差越大,最大到 stratum-15,stratum-16 表示不可达。
  • offset(偏移):本地时钟与上游时钟的时间差,单位一般是毫秒或微秒。chronyc tracking 里的 System time 就是当前估算的 offset。
  • delay(延迟):NTP 请求/响应在网络上的往返时间。chronyc tracking 里的 Root delay 是到根时钟的总延迟。
  • jitter(抖动):多次采样的 offset 方差,反映时钟稳定性。chronyc tracking 里的 RMS offset 与 jitter 类似。
  • reach(可达性):一个 8 bit 的移位寄存器,记录最近 8 次 poll 是否有响应,全部成功是 377(八进制 0o377 = 255),chronyc sources 最后一列就是这个值。
  • poll(轮询间隔):多久向源发一次请求,单位是 2 的幂秒。chronyc sources -v 里 Poll 列写的就是 2^n 里的 n,比如 6 表示 64 秒。
  • refid(参考 ID):上游时钟的标识,IP 或 stratum-0 设备名。
  • leap(闰秒状态):3 类,正常、插入一秒、删除一秒。2016 年和 2017 年初都出现过闰秒事件。

报文交互

简化流程:

  1. 客户端发 NTP request 给 server。
  2. server 在收到包时打上时间戳 T2,立刻发回 NTP response,里面带 T1(客户端发包时间,由客户端写入)、T2、T3(server 准备发包时间)。
  3. 客户端收到时记录 T4。
  4. 客户端通过 (T2 - T1) + (T4 - T3) 算 round-trip delay,通过 ((T2 - T1) + (T3 - T4)) / 2 算 offset。

这个简化模型假设网络对称,实际 chrony 会用更复杂的卡尔曼滤波估算 offset 和 jitter。

NTP 模式

  • client/server 模式:最常用,客户端从服务器拉时间。
  • symmetric 模式(mode 1/2):两个 server 互相同步,适合内网有多个 stratum-1 / 2 节点互备。
  • broadcast 模式:server 周期性广播,客户端被动接收,适合大子网。
  • manycast 模式:客户端发到多播组,最近的 server 应答,适合自动发现。
  • pool 模式pool.ntp.org 背后就是 DNS 轮询 + manycast 自动挑选健康源。

chrony 都支持。

chrony 与 ntpd 的取舍

优势对比

chrony 相对 ntpd 的优势:

  • 启动后能更快收敛到正确时间(几秒 vs 几分钟)。
  • 适合间歇性网络环境:笔记本、休眠、云服务器、容器节点、Wi-Fi 切换。
  • 适合虚拟机和容器,clock skew 估算更准。
  • 默认 slewing(微调),减少对应用的时间跳变。
  • 配置文件更短,可读性更好。
  • 自带 NTS(Network Time Security)支持,ntpd 集成较弱。
  • chronyc 交互式体验好,ntpq 略晦涩。

ntpd 相对 chrony 的优势:

  • 历史悠久,几乎所有发行版都默认带,老系统更兼容。
  • 严格遵循 RFC 5905,对老旧 NTP 设备兼容性更好。
  • 文档、案例、调优经验更丰富。
  • 第三方审计、安全加固资料多(ntpd 的历史漏洞、monlist 攻击等都有专门 mitigation)。

现状

  • RHEL 8 / 9、CentOS Stream 8 / 9、Rocky、AlmaLinux、openEuler 默认就是 chrony。
  • Ubuntu 18.04+、Debian 10+、SUSE 15+ 默认 chrony。
  • 一些金融、政府、运营商老系统还在用 ntpd,主要是历史原因。
  • 云厂商镜像(Aliyun、Tencent Cloud、华为云)默认都装 chrony。
  • K8s 节点上,kubelet 不会强依赖 chrony 或 ntpd,但 kube-apiserver、metrics-server、cert-manager 对时间漂移非常敏感。

选择建议

  • 新建集群、新建系统:直接 chrony。
  • 遗留 ntpd 集群:能升级就升级,升级前在测试集群跑一遍 NTP 同步验证。
  • 嵌入式、BusyBox、VyOS:chrony 也有包,ntpd 更紧凑,按需选择。
  • 严格合规行业:chrony + NTS 即可,比裸 NTP 安全。

时钟源选择

公有云厂商时钟源

不同云厂商通常提供内网 NTP 入口,延迟低、稳定:

  • 阿里云:ntp.aliyun.com(内网 ntp.cloud.aliyuncs.com,旧地址 time1.aliyun.com)。
  • 腾讯云:time1.cloud.tencent.comtime2.cloud.tencent.comtime3.cloud.tencent.comtime4.cloud.tencent.comtime5.cloud.tencent.com
  • 华为云:ntp.myhuaweicloud.com
  • AWS:默认 169.254.169.254 提供 Amazon Time Sync Service(基于 atomic clock),EC2 推荐用这个。
  • Azure:默认 time.windows.com 但建议切到自己的 time.nist.gov 链路。
  • GCP:默认 metadata.google.internal 提供 Google 内部 NTP。

云上实例的 chrony 配置里把这些地址放前面,本地时钟源延迟通常 < 5 ms。

公网常见时钟源

  • pool.ntp.org:全球志愿者 NTP 池,自动轮询,按地域分配节点(0.cn.pool.ntp.org1.asia.pool.ntp.org 等)。
  • time.cloudflare.com:Cloudflare 提供的 NTP,支持 NTS。
  • time.google.com:Google 公共 NTP。
  • time.apple.com:Apple 公共 NTP。

公网源的延迟通常 5-50 ms,受国际出口影响大。金融、政企、涉密网络不建议直接用公网源。

内网自建 NTP 服务器

推荐分层架构:

GPS / 北斗 / 原子钟(stratum-0 设备)
        ↓
Stratum-1 服务器(内网核心机房,1-2 台做 HA)
        ↓
Stratum-2 服务器(每个区域机房,2-4 台做 HA)
        ↓
业务服务器 / 容器节点 / 数据库 / 存储

stratum-1 服务器可以用:

  • 树莓派 + GPS 模块 + PPS(精度好,成本低)。
  • 商业 NTP 接收机(Meinberg、Symmetricom、Trimble)。
  • PTP(IEEE 1588)转 NTP 网关。
  • 公有云厂商的内网 NTP(很多银行 / 券商直接用,节省成本)。

闰秒、stepping、slewing

闰秒(Leap Second)

UTC 和 UT1(基于地球自转的时间)有累积差异,IERS 会不定期宣布在 6 月 30 日或 12 月 31 日最后一秒插入或删除 1 秒。最近一次是 2016-12-31,2017-01-01 多了 23:59:60 这一秒。

Linux 处理闰秒的方式:

  • 内核标记:内核打上 leap flag,应用读取时间后会看到 23:59:60。
  • 步进(step):chronyc makestep 或 ntp 某些版本会直接让时间跳 1 秒。
  • 涂抹(smear):Google、Meta(Facebook)、Cloudflare、AWS 都用"闰秒涂抹",把 1 秒均匀分摊到 24 小时内,绕开 23:59:60 的问题。chrony 可以配置 leapsecmode slew / slew / step / ignore,也可以配 smeartime 启用涂抹。

Stepping vs Slewing

  • slewing:chrony 默认做法,按 0.5 ms/s 或更慢的速度调整 system time(通过 adjtimex),应用感知不到。优点是不会导致时间跳变;缺点是大偏移收敛慢。
  • stepping:直接把 system time 改到目标值(通过 settimeofday)。会跳变,数据库、分布式系统、定时任务会出问题。chrony 只在 offset 超过 makestep 阈值(默认 1 秒)时才 step,或者首次启动时强制 step。
  • mktime/clock_gettime 注意事项:应用如果缓存了时间差(如 token TTL、HTTP Expires 头),step 会导致缓存的差值错乱。

chrony 推荐配置:makestep 1.0 3(offset > 1 秒且前 3 次更新才 step),之后再 slewing。生产里可以根据情况改阈值。

chrony 的体系结构

chronyd 是守护进程,负责同步、维护本地时间、调整 RTC。chronyc 是用户态控制工具。

chronyd 启动流程:

  1. 读取 /etc/chrony.conf(RHEL 系)或 /etc/chrony/chrony.conf(Debian 系)。
  2. 初始化时钟源、refclock、sourcestats、rtsvars。
  3. 启动后立刻尝试 step 系统时间(如果和上游差距大)。
  4. 持续轮询上游、估算 offset / delay / jitter、slewing 调整。

chronyd 还会:

  • 定期把 system time 同步到 RTC(rtcsync 指令)。
  • 提供 NTP server 服务给其他客户端(allow + local 指令)。
  • 维护 chrony.measure / tracking / sources / sourcestats 等状态。

chrony.conf 常用指令

按功能分组介绍。

上游时钟源

pool pool.ntp.org iburst maxsources 4
server time1.aliyun.com iburst
peer ntp01.internal iburst
refclock SHM 0 offset 0.5 delay 0.2
  • pool 解析为多个 IP,chrony 会从里面挑。
  • server 写死一个 IP。
  • peer 互相同步(symmetric 模式)。
  • refclock 用共享内存或 PPS 设备,适合自建 stratum-1。
  • iburst 启动时连续发 8 个包快速收敛。
  • minpoll / maxpoll 控制轮询间隔,如 minpoll 4 maxpoll 10 表示 16 秒到 1024 秒之间浮动。
  • prefer 优先选这个源。
  • trust 信任这个源。
  • xleave / nts 启用 NTS / interleave 模式。

访问控制

allow 192.168.0.0/16
allow 10.0.0.0/8
deny 0.0.0.0/0

同步行为

makestep 1.0 3
rtcsync
leapsecmode slew
smeartime 86400

客户端

local stratum 10
manual

local 表示本机即使没连到上游,也对外宣告自己是 stratum-10,集群内统一时间。manual 配合 chronyc settime 手动校准,但生产里慎用。

日志

log tracking measurements statistics
logdir /var/log/chrony
mailonchange myadmin@example.com 0.5

chronyc 工具

常用子命令:

  • chronyc tracking:综合状态。
  • chronyc sources -v / chronyc sources:列出源。
  • chronyc sourcestats -v:每个源的统计。
  • chronyc activity:最近 N 次 poll 的情况。
  • chronyc ntpdata:详细 NTP 报文。
  • chronyc waitsync 30 0.01:最多等 30 秒,offset 收敛到 0.01 秒以内。
  • chronyc makestep:强制 step。
  • chronyc tracking -p:显示偏移。
  • chronyc clients:列出连到本机的客户端(仅 server 模式)。
  • chronyc serverstats:server 模式下的请求统计。
  • chronyc delete `:移除某个源。
  • chronyc add server<addr>:临时加一个源(不写配置文件)。
  • chronyc accheck:检查 NTS 认证。
  • chronyc certif / cacert:NTS 证书管理。
  • chronyc -a makestep(systemd 环境):通过控制 socket 让守护进程 step。

chronyc 还有交互模式,输入 chronyc 回车进 prompt,help 列出所有子命令。

环境准备

硬件

  • 至少 1 核 CPU、512 MB 内存、100 MB 磁盘就能跑 chrony。
  • 内网 NTP 服务器建议用物理机(不带虚拟化),时钟稳定性最好。树莓派 + GPS 也是经典方案。
  • 服务器时钟源需要支持高频中断:现代 x86 服务器一般没问题,老旧 ARM 板卡要注意。

网络

  • UDP 123 端口:NTP 协议默认端口。客户端要能出站到上游 server,server 要能监听入站。
  • TCP 4460 端口:NTS(Network Time Security)需要。
  • 出入站都建议放通。云服务器要注意安全组规则。
  • NTP 反射放大攻击:chrony 默认不开 monlist 响应,比 ntpd 安全得多,但仍建议用 restrict 限制源 IP。

操作系统

  • RHEL 7 / 8 / 9、CentOS 7 / Stream 8/9、Rocky Linux、AlmaLinux、openEuler 20/22/24、Anolis OS。
  • Ubuntu 18.04 / 20.04 / 22.04 / 24.04。
  • Debian 10 / 11 / 12。
  • SUSE 12 / 15、openSUSE Leap。
  • 国产 UOS、麒麟、统信 Deepin。

内核要求:Linux 3.10+ 都没问题,2.6.32 老内核也支持 chrony 3.x / 4.x。

chrony 版本

  • chrony 1.30 / 2.x / 3.x:老版本,常见于 CentOS 7、Ubuntu 16。
  • chrony 4.x:当前主流,RHEL 9、Ubuntu 22.04 默认。
  • chrony 4.2+:开始支持 NTS 加密。

可以用 chronyd -v 或 chronyc --version 查看。

实战步骤

第 1 步:现状摸底

在动手改任何配置之前,先摸清楚当前状态,避免改了反而把生产搞乱。

查看系统时间、时区、RTC

date
date -u
timedatectl
hwclock
hwclock --utc
hwclock --localtime

timedatectl 输出关键字段:

  • Local time:当前系统时间。
  • Universal time:UTC 时间。
  • RTC time:硬件时间。
  • Time zone:时区。
  • System clock synchronized:是否同步过。
  • NTP service:是否启用了 systemd-timesyncd / chrony / ntpd。
  • RTC in local TZ:硬件时钟是否是 local 模式(应该为 no)。

查看 NTP 服务

systemctl status chronyd
systemctl status ntpd
systemctl status systemd-timesyncd

chronyc tracking
chronyc sources -v
chronyc sourcestats -v
chronyc activity

判断 NTP 是否在工作

chronyc tracking 输出关键字段解读:

  • Reference ID:上游源标识。
  • Stratum:当前 chronyd 估算的 stratum。
  • System time:当前 system time 与估算真实时间的偏差(带正负号)。
  • Last offset:上一次调整时的 offset。
  • RMS offset:长期 offset 的均方根,反映稳定性。
  • Frequency:本地时钟的频率漂移(ppm)。
  • Residual freq:残差频率。
  • Skew:频率估算的方差。
  • Root delay:到根时钟的总延迟。
  • Root dispersion:到根时钟的总离散度。
  • Update interval:更新间隔。
  • Leap status:闰秒状态(Normal / Insert second / Delete second)。

健康标准:

  • System time 绝对值 < 100 ms(公网)/ < 1 ms(内网)。
  • Last offset 绝对值 < 1 秒。
  • RMS offset 绝对值 < 1 秒。
  • Frequency 在 0 ppm 附近 ± 50 ppm。
  • Leap status 是 Normal

chronyc sources -v 输出关键列:

  • ^*:当前选中的源。
  • ^+:候选源。
  • ^-:备份源。
  • =?:未确认可达性。
  • ~:高抖动 / 不稳定。
  • M:异常状态。
  • x:被拒绝。
  • *:手工指定。
  • MS:接收异常。
  •  Reach:最后 8 次 poll 的成功次数(八进制)。

健康源:^* 或 ^+,Reach = 377,Last rx 距现在 < 2 个 poll 间隔。

chronyc sourcestats 输出当前 offset、jitter、reach、stability 等长期统计。

查看 NTP 端口

ss -ulnp | grep 123
netstat -ulnp | grep 123

chronyd 监听 0.0.0.0:123 还是 127.0.0.1:123 决定了是否对外提供 NTP 服务。

抓包确认

tcpdump -i any -n udp port 123 -c 20

看是否有 NTP 请求/响应,源/目的 IP 是否符合预期。

收集完这些信息,记到表格里

| 主机名 | 时区 | RTC | chrony 版本 | 上游 | offset | reach | 备注 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| web-01 | Asia/Shanghai | UTC | 4.1 | time1.aliyun.com | +0.3ms | 377 | 健康 |
| db-01 | Asia/Shanghai | UTC | 4.1 | time1.aliyun.com | -2.1s | 0 | 不可达 |

这一步是后面排查和验收的依据,不要省略。

第 2 步:时区配置

查看时区

timedatectl
ls -l /etc/localtime
cat /etc/timezone

修改时区

sudo timedatectl set-timezone Asia/Shanghai
sudo timedatectl set-timezone UTC
sudo timedatectl set-timezone Europe/Berlin

Asia/ShanghaiUTCEurope/Berlin 等是 IANA 时区数据库标准名,存在 /usr/share/zoneinfo/ 目录里。

RTC 同步模式

sudo timedatectl set-local-rtc 0

set-local-rtc 0 表示硬件时钟存 UTC;1 表示存 local time。生产环境强烈建议 0。

验证

timedatectl
date
date -u
hwclock --show --utc

容器内时区

容器 /etc/localtime 默认继承宿主机。如果要让容器用别的时区:

apiVersion:v1
kind:Pod
spec:
containers:
-name:app
image:my-app:1.0
volumeMounts:
-name:tz-config
mountPath:/etc/localtime
volumes:
-name:tz-config
hostPath:
path:/usr/share/zoneinfo/Asia/Shanghai
type:File

或者在 Dockerfile 里 ENV TZ=Asia/Shanghai + RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone。但容器镜像里塞时区文件不如直接挂宿主。

应用层时区

JVM 应用:-Duser.timezone=Asia/Shanghai 或 TZ 环境变量。 Python:os.environ['TZ'] + time.tzset()。 Node.js:TZ 环境变量。 MySQL:time_zone 参数 + CONVERT_TZ

容器内推荐把所有应用统一到 UTC,业务层按需转换。这样跨地域、跨集群、跨云排查日志时不会因为时区搞错。

第 3 步:chrony 安装

RHEL 9 / Rocky 9 / AlmaLinux 9 / CentOS Stream 9

sudo dnf install -y chrony
sudo systemctl enable --now chronyd
chronyc tracking

RHEL 8 / CentOS 8 / Rocky 8 / AlmaLinux 8

sudo dnf install -y chrony
sudo systemctl enable --now chronyd
chronyc tracking

CentOS 7 / RHEL 7

sudo yum install -y chrony
sudo systemctl enable --now chronyd
chronyc tracking

CentOS 7 上默认 chrony 3.4,能用但没 NTS。如需 NTS,需要 chrony 4.0+。

Ubuntu 22.04 / 24.04

sudo apt update
sudo apt install -y chrony
sudo systemctl enable --now chronyd
chronyc tracking

Ubuntu 22.04 默认 chrony 4.2+,自带 NTS。

Ubuntu 20.04

sudo apt update
sudo apt install -y chrony
sudo systemctl enable --now chronyd
chronyc tracking

Debian 11 / 12

sudo apt update
sudo apt install -y chrony
sudo systemctl enable --now chronyd
chronyc tracking

openEuler 20.03 / 22.03

sudo dnf install -y chrony
sudo systemctl enable --now chronyd
chronyc tracking

验证安装

chronyd -v
chronyc --version
rpm -q chrony
dpkg -l | grep chrony

第 4 步:上游时钟源选择与配置

按场景给几套配置模板。

模板 1:内网 + 公有云兜底(推荐大部分云服务器用)

# /etc/chrony.conf
# 优先用内网自建 NTP server
server ntp01.internal iburst prefer
server ntp02.internal iburst
# 公有云厂商作为兜底
server ntp.aliyun.com iburst
server time1.cloud.tencent.com iburst
# pool
pool pool.ntp.org iburst maxsources 4

# 启动时如果 offset > 1 秒,连续 3 次更新内允许 step
makestep 1.0 3

# 把系统时间同步到硬件时钟
rtcsync

# 硬件时钟调整间隔
rtcautotrim 30

# 同步到 RTC 的时间
hwclockfile /etc/adjtime

# 允许的客户端网段
allow 192.168.0.0/16
allow 10.0.0.0/8

# 默认拒绝其他来源
deny 0.0.0.0/0

# 拒绝所有 IPv6 来源
deny ::/0

# 日志
log tracking measurements statistics
logdir /var/log/chrony

模板 2:纯内网隔离环境(不连外网)

# /etc/chrony.conf
# 只用内网 NTP server
server ntp01.internal iburst prefer
server ntp02.internal iburst
server ntp03.internal iburst

# 上游不通时,本机仍然能对外提供服务
local stratum 10

makestep 1.0 3
rtcsync

allow 10.0.0.0/8
deny 0.0.0.0/0
deny ::/0

log tracking measurements statistics
logdir /var/log/chrony

模板 3:内网 NTP Server(自建 stratum-1 / 2)

# /etc/chrony.conf
# 这一台是 server 模式,对客户端提供服务

# 自身从上游同步(GPS、北斗、原子钟、或者内网根 server)
server ntp-master01.internal iburst prefer
server ntp-master02.internal iburst

# 允许客户端网段
allow 192.168.0.0/16
allow 10.0.0.0/8
allow 172.16.0.0/12
deny 0.0.0.0/0
deny ::/0

# 自身不睡醒调整 RTC,由其他机器负责
rtcsync

# 上游不可用时,自己作为 fallback
local stratum 10

log tracking measurements statistics
logdir /var/log/chrony

模板 4:NTS(Network Time Security)加密模式

# /etc/chrony.conf
# 需要 chrony 4.2+
server time.cloudflare.com iburst nts
server ntp.nts.sjtu.edu.cn iburst nts prefer
server ntp1.nts.lu iburst nts

makestep 1.0 3
rtcsync

# 限制外网访问,只允许自己出站
deny all

NTS 需要服务端支持,目前 Cloudflare、NIST、Some university 公开 NTP/NTS 节点。生产里更常见的做法是自建 NTS server:

# /etc/chrony.conf
ntsserverkey /etc/chrony/keys/ntp-server.key
ntstrustedcerts /etc/chrony/certs

模板 5:K8s 节点专用

# /etc/chrony.conf
# K8s 节点时间精度要求高(证书、metrics-server、kube-apiserver)
server ntp01.internal iburst prefer
server ntp02.internal iburst
server ntp.aliyun.com iburst

makestep 1.0 3
rtcsync

# 允许 Pod 共享 /dev/ptp 之类的设备
# 不需要 allow,因为 K8s 节点自身就是 client
deny all

# 关闭查询日志
log measurements statistics
logdir /var/log/chrony

模板 6:容器 / 边缘设备

# /etc/chrony.conf
# 适合间歇性网络、Wi-Fi 切换、4G 边缘盒子
pool pool.ntp.org iburst maxsources 4
server time1.aliyun.com iburst

makestep 1 1
rtcsync

# 边缘设备通常没有 RTC 持久化
# 需要时开启 fakehwclock

模板 7:NTP 反射攻击防御

# /etc/chrony.conf
# 限制哪些客户端能查询本机
allow 10.0.0.0/8
deny 0.0.0.0/0

# 不响应 monlist
noclientlog

# 限制每个客户端的查询频率
ratelimit interval 3 burst 8

chronyc clients 可以看当前连到本机的客户端。

第 5 步:重启和验证

修改完 /etc/chrony.conf 之后:

sudo systemctl restart chronyd
sudo systemctl status chronyd
chronyc tracking
chronyc sources -v
chronyc sourcestats -v
chronyc activity

看到 System time 收敛到合理范围(内网 < 1 ms,公网 < 50 ms),chronyc sources 状态列出现 ^*(主源),Reach 达到 377,就说明同步成功了。

chronyc waitsync 60 0.001 可以让 chrony 主动等到 offset < 1 ms:

chronyc waitsync 60 0.001

返回 0 表示成功,非 0 表示超时或异常。

第 6 步:日志和监控

日志

chrony 默认日志比较安静。要看更多细节:

# /etc/chrony.conf
log tracking measurements statistics
logdir /var/log/chrony

常用日志文件:

  • tracking.log:每个 update interval 的 offset / frequency。
  • measurements.log:原始 poll 测量。
  • statistics.log:长期统计。
  • temp.log:临时错误信息。

日志可以接入 rsyslog、ELK、Loki 等。

监控指标

chrony 自身没有内置 Prometheus exporter,但可以用以下几种方式接入:

  • chrony_exporter:第三方开源项目,提供 chrony_offset_secondschrony_frequency_ppm 等指标。
  • node_exporter 自带的 node_timex_* 指标。
  • 自定义脚本,从 chronyc tracking 解析。

示例 exporter 指标:

chrony_offset_seconds
chrony_frequency_ppm
chrony_skew_ppm
chrony_root_delay_seconds
chrony_root_dispersion_seconds
chrony_leap_status

chrony_leap_status 0 = Normal、1 = Insert second、2 = Delete second、3 = Not synchronized。

Prometheus 告警规则示例:

groups:
-name:chrony
rules:
-alert:ChronyOffsetTooLarge
expr:abs(chrony_offset_seconds)>0.1
for:5m
labels:
severity:warning
annotations:
summary:"主机 {{ $labels.instance }} 时间偏移过大"
description:"offset = {{ $value }} s"
-alert:ChronyNotSynced
expr:chrony_leap_status==3
for:1m
labels:
severity:critical
annotations:
summary:"主机 {{ $labels.instance }} NTP 未同步"

阈值的具体数值需要结合业务基线,不能照搬。

第 7 步:K8s 集群时间同步

K8s 集群对时间同步要求很高:

  • kube-apiserver 颁发的证书有开始/结束时间,节点时间不对证书直接报错。
  • metrics-server 拿 kubelet 数据,时间错位会导致 HPA 误判。
  • etcd 集群对时间敏感,时间漂移会导致 leader election 异常。
  • kube-scheduler 涉及时间戳。
  • 日志、audit log 顺序依赖时间。

K8s 节点配置推荐

# /etc/chrony.conf
server ntp01.internal iburst prefer
server ntp02.internal iburst
server ntp03.internal iburst

makestep 1.0 3
rtcsync

# 不要 allow,节点自身不向外提供 NTP
deny all

# 日志
log measurements statistics
logdir /var/log/chrony

K8s 节点时间检查

for n in $(kubectl get nodes -o name | cut -d/ -f2); do
echo"== $n =="
  kubectl debug node/$n -it --image=busybox -- \
    date -u
done

或用 Node Problem Detector(NPD)的时间漂移检测插件。

容器内时间

容器默认共享宿主 system time,不需要额外配置。但有些场景需要单独校准:

  • 容器内应用的 time() API 走的是 clock_gettime(CLOCK_REALTIME),返回宿主时间。
  • 容器内 monotonic clock 是容器进程启动后的单调时间,不是宿主启动时间。
  • 如果应用对 monotonic clock 起点有依赖(一般没有),可能会被混淆。

容器 time namespace 是 K8s 1.27+ 的 alpha 特性,可以让 Pod 有独立的时间视图。生产慎用。

物理机云上 K8s

云厂商的 K8s(ACK、TKE、EKS、GKE)会自动用云厂商的 NTP 服务,节点时间通常很准。但建议仍然配内网 NTP server 作为冗余。

第 8 步:故障排查

故障 1:chronyc sources 显示所有源都是 ^? 或 ^x

可能原因:

  • 防火墙阻挡 UDP 123。
  • 上游 NTP server 不通。
  • DNS 解析不到(pool、域名)。
  • restrict 配置错误。

排查步骤:

# 1. 测网络
ping ntp.aliyun.com
nc -uv ntp.aliyun.com 123

# 2. 测端口
nmap -sU -p 123 ntp.aliyun.com

# 3. 抓包
tcpdump -i eth0 -n udp port 123 -c 20

# 4. 看 chronyc
chronyc activity
chronyc ntpdata

修复:

  • 防火墙放行 UDP 123 出站。
  • 改用 IP 地址不用域名。
  • 检查上游是不是真的活着。

故障 2:offset 一直跳变(±几秒)

可能原因:

  • 源不稳定(公网源丢包率高)。
  • 主机 CPU 被打满,poll 间隔超时。
  • 虚拟机时间被 hypervisor 干扰。
  • rtcsync 写 RTC 太频繁。

排查:

# 1. 看 CPU
top
vmstat 1 5

# 2. 看 jitter
chronyc sourcestats -v

# 3. 看 reach
chronyc sources -v

# 4. 切到不同源
chronyc delete ntp.aliyun.com
chronyc add server time.google.com iburst

修复:

  • 换更稳定的源。
  • 加大 maxpoll 减少 poll 频率。
  • 关掉其他争用 CPU 的进程。
  • 检查 KVM / VMware Tools / Hyper-V 集成服务是否在干扰时钟。

故障 3:chronyc tracking 显示 System time 永远 ~0,但 date 偏差大

可能原因:

  • chrony 同步的是 internal "kernel time",但 settimeofday 调用被 seccomp 拦了。
  • 应用通过自己的方式改了 system time。

排查:

strace -f -e trace=clock_settime,settimeofday,adjtimex -p $(pidof chronyd)

故障 4:机器重启后时间错乱

可能原因:

  • 硬件时钟(RTC)漂移严重。
  • 操作系统没有把 system time 同步回 RTC。
  • rtcsync 没开。

修复:

# 同步 system time 到 RTC
sudo hwclock --systohc --utc

# 检查 adjtime 文件
cat /etc/adjtime
# 0.000000 1700000000 0.000000
# 1700000000 UTC

# /etc/chrony.conf 里加
rtcsync

故障 5:容器内时间漂移

可能原因:

  • 容器没特权但尝试改时间。
  • fakehwclock 没启用。
  • 容器 runtime 阻止时间调整。

修复:

  • 加 CAP_SYS_TIME capability。
  • 用 bind mount 共享宿主 /dev/ptp。
  • 启用 fakehwclock。
  • K8s 中加 securityContext.capabilities.add: ["SYS_TIME"](生产慎用)。

故障 6:双 NIC 多 IP 节点时间不同步

可能原因:

  • chrony 默认从所有接口收 NTP 包,路由表会选一个源 IP 发包。
  • 多 IP 节点上策略路由可能阻断。

修复:

# /etc/chrony.conf
bindaddress 192.168.1.10

把 chrony 绑到特定 IP。

故障 7:chronyd 启动失败

排查:

sudo journalctl -u chronyd -n 50
sudo chronyd -f /etc/chrony.conf -d

-d 调试模式打印所有内部状态。

故障 8:reach 一直是 0

可能原因:

  • server 配置错了 IP。
  • 上游 NTP server 不监听 UDP 123。
  • 防火墙双向都关了。

修复:

# 手动测
sudo ntpdate -q ntp.aliyun.com

注:ntpdate 在新系统已经被 chrony / ntpsec 替代,CentOS 7 后基本没有。

第 9 步:风险与回滚

风险 1:改了 chrony.conf 后同步失败

回滚:

# 备份
sudo cp /etc/chrony.conf /etc/chrony.conf.bak.$(date +%Y%m%d)

# 改回旧配置
sudo cp /etc/chrony.conf.bak.20260605 /etc/chrony.conf

# 重启
sudo systemctl restart chronyd

# 验证
chronyc tracking

风险 2:上游源时间不准,导致集群时间整体漂移

现象:所有节点都"看起来同步了",但都偏 10 秒。

排查:

chronyc tracking
# Reference ID 不是你预期的源

修复:

  • 切到可信源。
  • 强制 step:chronyc makestep

风险 3:强制 step 导致业务故障

风险高的场景:

  • 数据库主从:主从可能短暂不一致。
  • 分布式系统:lease 过期、心跳失联。
  • 证书校验:依赖时间戳的 token / cookie 失效。

应对:

  • 用 makestep 1.0 3 控制 step 频率。
  • 改成 slewing(默认)。
  • 业务层用 monotonic clock。

风险 4:chronyd 停服后系统时间缓慢漂移

# 看漂移
sudo systemctl stop chronyd
sleep 60
date
date
# 差几秒就说明硬件时钟漂移

应对:

  • 保持 chronyd 持续运行。
  • K8s 节点上 chronyd 容器 / systemd unit 不能停。

风险 5:K8s 节点时间漂移导致 cert-manager 续签失败

现象:证书过期、cert-manager Job 报错。

修复:

# 临时强制同步
sudo chronyc makestep
sudo systemctl restart chronyd

长期:

  • 配多个上游源。
  • 加 Prometheus 告警。

风险 6:UTC 模式 + 多时区管理员误判时间

有些运维习惯看 date 不带 -u,看到北京时间。容器 / 服务器混部时容易混。

建议:

  • 服务器统一 UTC,应用按需转换。
  • 日志统一 UTC 时间戳。
  • 内部约定"我们看 UTC,业务方看本地"。

风险 7:自建 NTP Server 时间源硬件故障

应对:

  • 至少 2 台 stratum-1 服务器做主备。
  • GPS / 北斗接收机双机热备。
  • 监控 stratum-1 偏移量告警。

第 10 步:合规与等保

等保 2.0 中关于时间同步的条款:

  • 应当在网络边界、重要网络节点进行安全审计,审计覆盖到每个用户。
  • 应对分散在各个设备上的审计数据进行收集集中存储和集中分析。
  • 应能对网络行为、主机行为、应用行为等进行时间戳标记,时间源应可信。

实操建议:

  1. 所有服务器配置 NTP,时间源至少包含 2 个独立源。
  2. 部署内部 NTP 服务器,连接国家级时间源(北斗 / GPS / 国家授时中心 / 国家时间频率计量中心)。
  3. 日志带时间戳,统一 UTC。
  4. 周期性审计:
    • chronyc tracking 截图。
    • chronyc sources -v 截图。
    • 配置文件 diff。
  5. 自动化检查脚本(下面会给)。

合规检查脚本(Ansible 示例)

# /etc/ansible/playbooks/chrony-check.yml
-name:检查NTP配置
hosts:all
gather_facts:yes
tasks:
-name:确认chronyd在运行
systemd:
name:chronyd
state:started
enabled:yes
register:chrony_status

-name:收集chronytracking
command:chronyctracking
register:tracking
changed_when:false

-name:收集chronysources
command:chronycsources-v
register:sources
changed_when:false

-name:输出报告
debug:
msg:|
          主机: {{ inventory_hostname }}
          跟踪: {{ tracking.stdout }}
          源: {{ sources.stdout }}

合规检查脚本(Bash 示例)

#!/usr/bin/env bash
# /usr/local/bin/chrony-audit.sh
# 检查所有受控主机的 NTP 状态

LOG_DIR=/var/log/chrony-audit
mkdir -p "$LOG_DIR"
REPORT="$LOG_DIR/audit-$(date +%Y%m%d).log"

for host in $(cat /etc/hosts.list); do
echo"=== $host ===" >> "$REPORT"
  ssh -o StrictHostKeyChecking=accept-new "$host" \
'chronyc tracking; echo "---"; chronyc sources -v' \
    >> "$REPORT" 2>&1
done

# 找 offset > 1 秒的主机
grep -B1 -E "System time.*-?\d+\.\d{6} seconds""$REPORT" \
  | awk '/^=== / {host=$2} /System time/ {
    val=$4
    if (val+0 > 1.0 || val+0 < -1.0) print host": offset "val" 秒超限"
  }'


# 找未同步的主机
grep -B5 "Leap status : Not synchronized""$REPORT" \
  | awk '/^=== / {print $2": 未同步"}'

批量配置管理

用 Ansible / SaltStack / Puppet 批量分发 /etc/chrony.conf

# ansible: roles/chrony/tasks/main.yml
-name:安装chrony
package:
name:chrony
state:present

-name:分发配置文件
template:
src:chrony.conf.j2
dest:/etc/chrony.conf
owner:root
group:root
mode:'0644'
notify:restartchronyd

-name:启动并开机自启
service:
name:chronyd
state:started
enabled:yes

Jinja2 模板按环境区分:

# ansible: roles/chrony/templates/chrony.conf.j2
{% if env == 'prod' %}
server ntp01.prod.internal iburst prefer
server ntp02.prod.internal iburst
{% elif env == 'dev' %}
server ntp01.dev.internal iburst
server ntp.aliyun.com iburst
{% endif %}
makestep 1.0 3
rtcsync
allow {{ ntp_allow_net }}
deny 0.0.0.0/0
deny ::/0
log tracking measurements statistics
logdir /var/log/chrony

第 11 步:进阶方向

NTS(Network Time Security)

NTS 是 IETF RFC 8915 定义的 NTP 加密扩展,目标是解决 NTP 流量被篡改、伪造的问题。

chrony 4.2+ 原生支持。配置:

server time.cloudflare.com iburst nts
server ntp.nts.sjtu.edu.cn iburst nts

可以用 chronyc accheck 查看认证状态。

PTP(IEEE 1588 Precision Time Protocol)

金融交易、5G、工业控制场景需要微秒甚至纳秒级时间同步。PTP 适合这些场景。

chrony 4.x 增加了 PTP 支持(refclock PHC),可以把 PTP 主时钟时间同步到系统时间。

GPS / 北斗 + chrony

自建 stratum-1 经典方案:

  • GPS 模块:u-blox NEO-M8N、Neo-6M,性价比高。
  • 北斗模块:UM220、AT6558R,国内合规友好。
  • PPS 信号:从 GPS 出来的高精度秒脉冲,连到树莓派 GPIO。
  • chrony 配 refclock PPS /dev/pps0 + refclock SHM 0
# /etc/chrony.conf
refclock PPS /dev/pps0 lock GPS
refclock SHM 0 offset 0.5 delay 0.2 refid GPS

Stratum-1 自建清单

  • 树莓派 4B / 5 + GPS 模块 + PPS 天线。
  • 恒温晶振(OCXO)板卡,可选。
  • chrony 4.x + gpsd。
  • 至少 2 台做主备。
  • 监控:用 chrony_exporter 抓 chrony_stratum 等指标。

时间同步 + 监控告警组合

  • Prometheus 抓 chrony_exporter。
  • Grafana 看板:offset、reach、stratum、leap status、frequency 趋势。
  • Alertmanager 告警:offset > 100 ms、reach = 0、leap status != Normal。

常用命令清单

时间查看

date
date -u
date '+%Y-%m-%d %H:%M:%S.%N'
date -d @1700000000
date -d '2026-06-05 10:00:00 UTC' +%s
hwclock
hwclock --show --utc
hwclock --show --localtime
hwclock --systohc --utc
hwclock --hctosys --utc
timedatectl
timedatectl status
cat /etc/timezone
ls -l /etc/localtime
zdump -v /usr/share/zoneinfo/Asia/Shanghai

chrony 服务

systemctl start chronyd
systemctl stop chronyd
systemctl restart chronyd
systemctl status chronyd
systemctl enable chronyd
systemctl disable chronyd
chronyd -f /etc/chrony.conf -d
chronyd -Q -t 5 'server time.aliyun.com iburst'
journalctl -u chronyd -f

chronyc

chronyc tracking
chronyc sources -v
chronyc sourcestats -v
chronyc activity
chronyc ntpdata
chronyc clients
chronyc serverstats
chronyc waitsync 30 0.001
chronyc makestep
chronyc -a makestep
chronyc delete 192.168.1.10
chronyc add server 10.0.0.1 iburst
chronyc accheck
chronyc tracking -p
chronyc -h ntp01.internal

网络与端口

ss -ulnp | grep 123
netstat -ulnp | grep 123
nc -uv time.aliyun.com 123
nmap -sU -p 123 time.aliyun.com
tcpdump -i eth0 -n udp port 123 -c 20
tcpdump -i eth0 -n udp port 123 -w /tmp/ntp.pcap

调试

strace -f -e trace=clock_settime,settimeofday,adjtimex -p $(pidof chronyd)
gdb -p $(pidof chronyd) --batch -ex 'thread apply all bt' -ex detach
journalctl -u chronyd -p debug

NTP 客户端工具

# ntpdate 已被 chrony 替代,但很多老脚本还在用
ntpdate -q ntp.aliyun.com
sntp -S ntp.aliyun.com

# busybox 内置
busybox ntpd -q -p ntp.aliyun.com

文件路径

/etc/chrony.conf
/etc/chrony/chrony.conf
/etc/chrony.d/*.conf
/etc/chrony.keys
/etc/chrony/ntp.keys
/var/log/chrony/
/var/lib/chrony/
/usr/bin/chronyc
/usr/sbin/chronyd
/usr/share/zoneinfo/
/etc/localtime
/etc/timezone
/etc/adjtime

配置示例汇总

内网 NTP Server(stratum-2 / GPS 接入)

# /etc/chrony.conf
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

# 从上游同步
server ntp-master01.internal iburst prefer
server ntp-master02.internal iburst

# 自定义 NTP Server 监听端口
bindaddress 192.168.100.10
allow 192.168.0.0/16
allow 10.0.0.0/8
allow 172.16.0.0/12
deny 0.0.0.0/0
deny ::/0

# 上游不可用时作为 fallback
local stratum 10

# 限制 monlist 行为,防反射
noclientlog
ratelimit interval 3 burst 8

# 启用 NTS(如果上游支持)
ntsserverkey /etc/chrony/ntpserver.key
ntstrustedcerts /etc/chrony/cacert.pem

# 日志
log tracking measurements statistics
logdir /var/log/chrony

内网 NTP Client(应用服务器)

# /etc/chrony.conf
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

server ntp01.internal iburst prefer
server ntp02.internal iburst
server ntp03.internal iburst

# 不对外提供服务
deny all

# 监控
log measurements statistics
logdir /var/log/chrony

K8s node 客户端

# /etc/chrony.conf
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

server ntp01.internal iburst prefer
server ntp02.internal iburst
server ntp.aliyun.com iburst

# 不对外服务
deny all

# 日志
log measurements statistics
logdir /var/log/chrony

边缘 / 4G 网关

# /etc/chrony.conf
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

# 间歇性网络,用 pool 自动挑
pool pool.ntp.org iburst maxsources 4
server time1.aliyun.com iburst

# 容忍更慢收敛
maxpoll 12
minpoll 6

# 边端不开 server
deny all

物理机自建 stratum-1(GPS + PPS)

# /etc/chrony.conf
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

# GPS + PPS
refclock PPS /dev/pps0 lock GPS prefer
refclock SHM 0 offset 0.5 delay 0.2 refid GPS noselect
refclock SOCK /var/run/chrony.gpsd.sock refid GPS noselect

# 对外服务
bindaddress 192.168.100.10
allow 192.168.0.0/16
allow 10.0.0.0/8
deny 0.0.0.0/0
deny ::/0

# 上游断网兜底
local stratum 1

# 防止反射
noclientlog
ratelimit interval 3 burst 8

# NTS
ntsserverkey /etc/chrony/ntpserver.key

log tracking measurements statistics
logdir /var/log/chrony

NTS 加密模式

# /etc/chrony.conf
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

server time.cloudflare.com iburst nts
server ntp.nts.sjtu.edu.cn iburst nts prefer
server ntp1.nts.lu iburst nts

deny all
log measurements statistics
logdir /var/log/chrony

排查思路

排查表

| 现象 | 检查点 | 命令 | 关键指标 | 结论 |
| --- | --- | --- | --- | --- |
| offset 很大 | 防火墙 | nc -uv time.aliyun.com 123 | 通/不通 | 防火墙挡了 |
| offset 很大 | 上游源 | chronyc sources -v | Reach | 源不可达 |
| offset 跳变 | CPU 抢占 | top, mpstat | %idle | CPU 满 |
| offset 跳变 | hypervisor 干扰 | chronyc sourcestats | jitter | 虚拟化漂移 |
| chronyc 异常 | 日志 | journalctl -u chronyd | error | 配置错误 |
| 容器时间漂移 | 权限 | docker inspect | CapEff | 缺少 SYS_TIME |
| 节点 NotReady | 时间差 | date -u vs kube-apiserver | 证书过期 | 证书时间错位 |
| 日志顺序乱 | NTP 同步状态 | chronyc tracking | System time | 主机时间不统一 |

排查流程

  1. 看现象date 不对?hwclock 不对?业务报错?
  2. 看服务systemctl status chronydjournalctl -u chronyd
  3. 看状态chronyc trackingchronyc sources -v
  4. 看网络ss -ulnp | grep 123nc -uvtcpdump
  5. 看 CPU/IOtopiostatvmstat
  6. 看时区timedatectlcat /etc/timezone
  7. 看 RTChwclock --show --utc
  8. 看容器:宿主时间、容器时间对比。
  9. 定位根因:根据上面信息判断是网络、CPU、配置、硬件、内核哪种。
  10. 修复:按根因修复。
  11. 验证chronyc waitsync 60 0.001、跨主机 date +%s%N
  12. 复盘:写事故复盘文档,更新监控。

风险提醒汇总

  1. 强制 chronyc makestep 会让 system time 跳变,可能影响数据库、分布式系统、证书校验、定时任务。
  2. 改 /etc/chrony.conf 之后必须 systemctl restart chronyd,否则不生效。
  3. allow 0.0.0.0/0 是 NTP 反射攻击温床,必须加 restrict 或 deny 0.0.0.0/0
  4. 自建 NTP Server 必须有冗余,单点故障会导致整集群时间错乱。
  5. RTC 模式改成 local 会让跨时区机器时间错乱,建议保持 UTC。
  6. pool.ntp.org 节点是志愿者维护,质量参差,生产建议用云厂商或自建。
  7. ntpd 历史漏洞(mode 7 monlist、NTP 反射攻击)很多,新系统建议直接 chrony。
  8. K8s 节点时间漂移会引发 NotReadyx509 错误、cert-manager 续签失败等多种问题。
  9. 应用层应使用 monotonic clock,不要把 CLOCK_REALTIME 当成"时间戳"用。
  10. 数据库主从复制延迟如果和 offset 跳变同时出现,要先确认时间同步是否正常。

验证方式

同步验证

# 1. 实时 offset
chronyc tracking
# System time 接近 0

# 2. 等待收敛
chronyc waitsync 60 0.001
# 返回 0

# 3. 源健康
chronyc sources -v
# ^* 状态,Reach 377

# 4. 长期稳定
chronyc sourcestats -v
# offset 趋势平,jitter < 1ms

# 5. RTC 同步
hwclock --show --utc
# 接近 system time

跨主机对比

# 在 5 台机器上同时跑
for h in web01 web02 db01 db02 cache01; do
  ssh $h"date '+%s.%N'"
done

5 台机器的时间差应该 < 10 ms(内网)/ < 100 ms(公网)。

断网测试

sudo iptables -A OUTPUT -p udp --dport 123 -j DROP
sleep 3600
date
# 1 小时后看漂移
sudo iptables -D OUTPUT -p udp --dport 123 -j DROP

漂移 < 5 秒说明硬件时钟健康。

压力测试

# 跑 stress-ng
stress-ng --cpu 4 --vm 2 --vm-bytes 1G --timeout 600
# 同时看 chronyc
watch -n 1 'chronyc tracking'

应该看到 offset 略有波动但很快收敛。

业务验证

  • 数据库主从延迟:SHOW SLAVE STATUS(MySQL 5.7)/ SHOW REPLICA STATUS(MySQL 8.0)里 Seconds_Behind_Master 接近 0。
  • K8s 节点:kubectl get nodes 全是 Ready
  • 证书:openssl x509 -in cert.pem -noout -dates 输出与 date 一致。
  • 日志:相邻机器同一时刻的日志时间戳差 < 1 秒。
  • 分布式系统心跳:服务间 RPC 心跳正常。

回滚方案

改了 /etc/chrony.conf 出问题

# 1. 备份当前配置
sudo cp /etc/chrony.conf /etc/chrony.conf.broken.$(date +%Y%m%d)

# 2. 恢复备份
sudo cp /etc/chrony.conf.bak.$(date +%Y%m%d) /etc/chrony.conf

# 3. 重启
sudo systemctl restart chronyd

# 4. 验证
chronyc tracking

整台机器时间错乱要回滚

# 1. 停 chrony
sudo systemctl stop chronyd

# 2. 手动设时间(用可信源)
sudo ntpdate ntp.aliyun.com
# 或者
sudo sntp -S time.aliyun.com

# 3. 同步到 RTC
sudo hwclock --systohc --utc

# 4. 启动 chrony
sudo systemctl start chronyd

# 5. 验证
chronyc tracking
date
hwclock

K8s 节点时间错乱

# 1. cordon 节点
kubectl cordon node-01

# 2. 排空
kubectl drain node-01 --ignore-daemonsets

# 3. SSH 登录节点,强制同步
sudo systemctl stop chronyd
sudo ntpdate ntp01.internal
sudo systemctl start chronyd
chronyc tracking

# 4. uncordon
kubectl uncordon node-01

整集群时间错乱

极少见,通常是上游 NTP Server 时间错乱或恶意攻击。

# 1. 切到备用上游
# 修改 /etc/chrony.conf 的 server 指令
sudo sed -i 's/^server .*/server ntp-master01.internal iburst prefer/' /etc/chrony.conf
sudo systemctl restart chronyd

# 2. 强制 step
chronyc makestep

# 3. 监控
chronyc tracking

总结

时间同步看似基础,但实际是 Linux 运维最容易被低估的一块。chrony 是当前最主流的 NTP 客户端/服务器实现,能覆盖从云服务器、容器、K8s 节点到自建 stratum-1 的所有场景。

核心要点:

  • 明确时区、UTC、硬件时钟的关系,统一集群时区。
  • 选可信上游:内网 + 云厂商 + 公网 pool 三层兜底。
  • 用 makestep 1.0 3 限制大步 step,其余靠 slewing。
  • 启用 NTS 防止 NTP 流量被篡改。
  • 至少 2 个独立上游源,监控 reach、offset、stratum。
  • 把时间指标接入 Prometheus + Grafana + Alertmanager。
  • K8s 节点、自建 NTP server、容器宿主分别给模板。
  • 等保 / 行业合规做自动化检查脚本。
  • 应用层使用 monotonic clock 而不是 wall clock。

进阶方向:

  • NTS 加密、PTP 高精度。
  • 自建 stratum-1 + GPS / 北斗。
  • chrony_exporter + Prometheus 完整监控。
  • 与 CIS Benchmark、SLSA、零信任架构集成。

附录

关键路径

  • 配置:/etc/chrony.conf(RHEL / openEuler / AlmaLinux)、/etc/chrony/chrony.conf(Debian / Ubuntu)。
  • 漂移文件:/var/lib/chrony/drift
  • 日志目录:/var/log/chrony/
  • 控制 socket:/var/run/chrony/chronyd.sock
  • 工具:/usr/bin/chronyc/usr/sbin/chronyd
  • 时区数据:/usr/share/zoneinfo/
  • 本地时区:/etc/localtime
  • 时区名:/etc/timezone

关键环境变量

  • TZ:POSIX 系统设置时区。
  • chronyc_TZ:影响 chronyc 输出的时区。

关键端口

  • UDP 123:NTP。
  • TCP 4460:NTS(KE 阶段)。
  • TCP 3731:chrony cmdmonitor(可选,远程 chronyc 接入)。

关键文件

  • /etc/chrony.keys:对称密钥(NTP authentication)。
  • /etc/adjtime:hwclock 状态。
  • /etc/ntp.conf:ntpd 配置(如果并存)。
  • /etc/systemd/timesyncd.conf:systemd-timesyncd 配置。

关键链接

  • chrony 官方:http://chrony.tuxfamily.org/
  • chrony GitHub:https://github.com/keplerproject/chrony
  • NTP Pool:https://www.pool.ntp.org/
  • Cloudflare NTS:https://blog.cloudflare.com/secure-time/
  • IETF NTS:https://datatracker.ietf.org/doc/rfc8915/
  • IETF NTP:https://datatracker.ietf.org/doc/rfc5905/

版本兼容

  • chrony 1.x:老版本,没有 NTS、没有 tsdb。
  • chrony 2.x:成熟稳定,CentOS 7 默认。
  • chrony 3.x:加入更多 refclock 支持。
  • chrony 4.x:NTS、PTP、PHC、Canned config、async transfer。
  • 4.2+:NTS KE / NTS EF 完整支持。

具体指令以实际版本为准。

常见错误码

  • 503 No suitable source:所有源都不可达。
  • 500 Too many sources:源超过 maxsources。
  • 504 Source not found:要删除的源不存在。
  • 522 Reachability not yet achieved:reach 还没达到 1。

具体错误以 chronyc 输出为准。

写给初中级读者的最后建议

  1. 时间同步是基础设施,先把 /etc/chrony.conf 写好,再考虑监控。
  2. 不要照搬网上搜到的 chrony.conf,看清楚每个指令含义再上生产。
  3. 改配置前先备份,先在测试集群跑一遍。
  4. chronyc tracking 是日常排查第一命令,先看这个。
  5. 监控和告警先做,事后复盘才有数据。
  6. K8s 节点、自建 NTP Server、数据库主库这三种角色优先级最高。
  7. 出问题不要怕回滚,备份和回滚流程是日常必备。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 08:13:50 HTTP/2.0 GET : https://f.mffb.com.cn/a/497981.html
  2. 运行时间 : 0.250923s [ 吞吐率:3.99req/s ] 内存消耗:4,783.47kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=7fd53257b94ca03b5bded994778a651f
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000932s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001379s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.004686s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.004798s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001538s ]
  6. SELECT * FROM `set` [ RunTime:0.008857s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001623s ]
  8. SELECT * FROM `article` WHERE `id` = 497981 LIMIT 1 [ RunTime:0.001914s ]
  9. UPDATE `article` SET `lasttime` = 1783037631 WHERE `id` = 497981 [ RunTime:0.010882s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.007642s ]
  11. SELECT * FROM `article` WHERE `id` < 497981 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.009699s ]
  12. SELECT * FROM `article` WHERE `id` > 497981 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001473s ]
  13. SELECT * FROM `article` WHERE `id` < 497981 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.045361s ]
  14. SELECT * FROM `article` WHERE `id` < 497981 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.014293s ]
  15. SELECT * FROM `article` WHERE `id` < 497981 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.027516s ]
0.254642s