Skip to content

分布式时间、Deadline、租约与时钟回拨面试题

本页只放标准回答、追问和知识页精确跳转。

1. currentTimeMillis()nanoTime() 有什么区别

标准回答: currentTimeMillis() 表达可被校正的墙上时间,适合日期、日志和现实时间校验;nanoTime() 来源是单调时间域,只能做同一 JVM 内的差值,适合耗时和 Deadline。nanoTime() 不能转日期、持久化或跨进程比较。

原理:时间类型单调时钟

2. 为什么不能用 currentTimeMillis() 计算接口耗时

标准回答: 系统墙上时间可能因 NTP、人工校时或虚拟机恢复向前或向后跳,时间差可能异常甚至为负。接口持续时间应使用单调时钟;业务发生日期仍使用带时区的墙上时间。

原理:墙上时钟

3. NTP 能保证所有机器时间完全一致吗

标准回答: 不能。NTP 根据报文时间戳估算 Delay 和 Offset,受到网络不对称、时间源质量和本机振荡器影响。它可以降低偏差,但仍需监控 Offset、Jitter、Root Dispersion 和 Reachability,不能用物理时间戳代替因果或业务版本。

原理:NTP 原理与边界

4. Slew 和 Step 有什么区别

标准回答: Slew 通过轻微调整时钟速率逐渐消除偏差,减少跳变;Step 直接跳到目标时间,收敛快但运行中应用会观察到前跳或回拨。具体策略取决于校时程序、配置和偏差大小。

原理:Slew 与 Step

5. 跨服务为什么优先传播剩余超时,而不是绝对截止时间

标准回答: 两台机器的墙上时钟存在偏差,直接比较绝对截止时间会错误增加或减少预算。入口用单调时钟维护总预算,每一跳扣除已耗时和返回余量,传播受限的剩余 Duration;接收方再建立本地单调 Deadline。

原理:Deadline 传播

6. 租约过期后旧持有者为什么还能写

标准回答: 旧持有者可能经历长 GC、进程暂停或网络隔离,服务端已将租约授予新节点,但旧节点恢复后尚未感知失效,仍会继续执行。租约降低并发概率,最终副作用资源必须使用单调 Fencing Token 拒绝旧持有者。

原理:租约安全

7. Fencing Token 应该在哪里校验

标准回答: 必须在真正产生副作用的资源端,例如数据库、存储、设备网关。客户端在写前检查锁仍存在有竞态窗口,检查后可能立即暂停;资源端只接受大于已见最大 Token 的写,才能拒绝恢复后的旧持有者。

原理:Fencing Token

8. Snowflake 遇到时钟回拨怎么办

标准回答: 短回拨可在明确上限内等待;长回拨应拒绝并告警、切换经过证明不冲突的节点空间,或使用持久化逻辑时间。不能直接按较小时间戳继续生成,否则同 WorkerId 和序列组合可能与历史 ID 冲突。

原理:Snowflake 与回拨

9. JWT 为什么会突然提示尚未生效或已经过期

标准回答: expnbfiat 依赖 UTC 墙上时间,签发方和验证方时钟偏差可能造成边界误判。应修复时间同步并设置小而明确的 Clock Skew,不能无限放宽窗口,否则会延长过期 Token 的有效期。

原理:JWT 与时间边界

10. 为什么 Trace 中子 Span 可能显示在父 Span 之前

标准回答: 不同服务使用各自墙上时钟记录开始时间,时钟偏差会造成跨节点时间轴倒置。排查应结合每个进程的单调 Duration、协议发送接收事件、NTP Offset 和日志,不能只凭可视化横轴判断因果。

原理:Trace 时间

11. 线上怀疑时钟问题怎样取证

标准回答: 先区分问题依赖墙上时间、经过时长、租约还是业务版本;收集 UTC、时区、NTP/Chrony Offset、Jitter、时间源和异常窗口校时记录;再核对数据库、缓存、注册中心、Token/证书、WorkerId、租约 Token 和 GC 暂停,最后按业务版本恢复而不是盲目改时间。

原理:时间异常 Runbook