单调时钟与墙上时钟的区别?ntp如何优雅校时?

发布于:2022-11-29 ⋅ 阅读:(289) ⋅ 点赞:(0)

目录

墙上时钟

单调时钟

如何解决?

墙上时钟

根据某个日历返回当前的日期与时间。

  • Linux 上的 clock_gettime(CLOCK_REALTIME)
  • Java 中的 System.currentTimeMills()

会返回 1970-01-01(UTC)的时间戳(秒和毫秒)。

墙上时钟会和 NTP 服务器同步产生跳跃导致一些奇怪的问题。

单调时钟

更适合测量持续时间段(时间间隔),如超时或服务的响应时间。保证总是向前(不会出现墙上时钟的回拨现象)。

  • Linux 上的 clock_gettime(CLOCK_MONOTONIC)
  • Java 中的 System.nanoTime()

单调时钟多个节点的对比没有任何意义,多路 CPU 可能有单独的计时器,且不与其他 CPU 进行同步。由操作系统进行补偿它们之间的偏差。

NTP 检测到本地石英比时间服务器更快或者更慢,NTP 会调整本地石英的震动频率(摆动),最大幅度为 0.05%。 NTP 并不会直接调整单调时钟向前或回拨 。

如何解决?

t2 的时间真的会比 t1 小吗?

这里就牵涉出 2 个概念:墙上时钟、单调时钟,它们之间有什么区别呢?

  • 墙上时钟:通常就是指前面讲到的世界协调时 UTC,校准时间后,可能发生回拨

  • 单调时钟:计算机自启动以后经历的纳秒数,不会回拨

t1 = time.now()
// 时间发生校准
t2 = time.now()

// t2比t1小怎么办?
elapsed = t2 - t1

一般我们写的代码,像上面程序调用的「时间 API」,通常获取的时间是墙上时钟,所以,如果时间发生校准,就可能会发生「时光倒流」的情况。

这必然对程序产生很大的影响,怎么解决这个问题呢?

幸运的是,NTP 在校准时间时,提供了 2 种方式:

  1. ntpdate:一切以服务端时间为准,「强制修改」本机时间

  2. ntpd:采用「润物细无声」的方式修改本机时间,把时间差均摊到每次小的调整上

也就是说,ntpd 当接收到需要「回拨」的时间时,会让本机时间走得「慢」一点,小步调整,逐渐与服务端的时钟「对齐」,这样一来,本机时间依旧是递增的,避免发生「倒流」。

当我们在配置 ntp 服务时,需要格外注意这种情况。另外,在编写程序时,也要注意调用的时间 API 获取的是哪个时间,避免业务逻辑发生异常。

 

本文含有隐藏内容,请 开通VIP 后查看