Network Time Protocol (NTP) is an internet protocol used to synchronize with computer clock time sources in a network. It belongs to and is one of the oldest parts of the TCP/IP suite. The term NTP applies to both the protocol and the client-server programs that run on computers.

Mac 中可以在设置中找到 NTP 服务器的地址,比如下图中的地址就是 time.apple.com

Figure 1: NTP

Figure 1: NTP

Estimating time over a network

Figure 2: NTP

Figure 2: NTP

  1. Round-trip network delay: \(\delta = (t_{4} - t_{1}) - (t_{3} - t_{2})\)

  2. Estimated server time when client receives response: \(t_{3} + \frac{\delta}{2}\)(客户端收到响应时的服务器的时间)

  3. Estimated clock skew: \(\theta = t_{3} + \frac{\delta}{2} - t_{4} = \frac{(t_{2} - t_{1} + t_{3} - t_{4})}{2}\)(计算预估的服务器时间和当前客户端时间的偏差)

Correcting clock skew

Once the client has estimated the clock skew θ, it needs to apply that correction to its clock.

  • if \(\theta < 125 ms\), slew the clock:

    slightly speed it up or slow it down by up to \(500 ppm\)1 (brings clocks in sync within ≈ 5 minutes)

  • if \(125 ms \le \theta < 1000 s\), step the clock:

    suddenly reset client clock to estimated server timestamp

  • if \(\theta \ge 1000 s\), panic and do nothing (leave the problem for a human operator to resolve)

依靠时钟同步的系统需要监控时钟偏移。从最后一条可以看出,如果 NTP Client 和 NTP Server 偏差过大,则会拒绝同步 NTP 的时间,留给人工来处理,因此我们需要避免出现这种偏差过大的情况。

当初初学 Java 的时候,需要知晓某个函数或某段代码执行的时间,通常会用 System.currentTimeMillis() 来测量

原来 System.currentTimeMillis() 用来测量某个函数运行的时间是错误的,会受到 NTP 的影响(机率虽然很小)。应该用 System.nanoTime() 来测量,不会受到 NTP 很大的影响,最多影响「单调时间」步进的频率。


  1. 1 ppm = 1 microsecond/second = 86ms/day = 32s/year (ppm 是 part per million 的简称) ↩︎


Links to this note