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
。
Estimating time over a network
-
Round-trip network delay: \(\delta = (t_{4} - t_{1}) - (t_{3} - t_{2})\)
-
Estimated server time when client receives response: \(t_{3} + \frac{\delta}{2}\)(客户端收到响应时的服务器的时间)
-
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 ppm = 1 microsecond/second = 86ms/day = 32s/year (ppm 是 part per million 的简称) ↩︎