时间同步
时间同步(计算机如何同步时间)
在 *** 世界里,计算机要想协同工作,时间同步是一个非常重要的基础。计算机内部有自己的时间,这个时间是通过内部晶体振荡器产生的固定频率来模拟时间的流逝而计算出来的。虽然频率很稳定,但也有误差,虽然目前的技术水平误差很小。(具体的振荡原理这里就不展示了。)
由于本地时间会产生误差,所以会造成两台服务器的时间不一致。要消除不一致,需要有一个统一的时间标准,然后大家以这个标准为基准时间,校准自己的本地时间,这样不仅协调了世界时(UTC),这个时间是怎么来的不是本文的重点。
好的,现在,另一个地方有一个标准时间。如何通过 *** 将这个标准时间与您的本地计算机同步?如何在同步的过程中尽可能的消除 *** 延迟的影响?
有没有可能直接发出一个 *** 请求,然后得到一个返回时间戳,修改本地时间?显然不是。别忘了,数据包在 *** 中传输是需要时间的。你不知道这个请求从对方到达本地电脑需要多长时间,延迟会严重影响时间校准的结果。
好了,现在的问题是 *** 延迟。如果能消除 *** 延迟,就能精确同步,但以现在的技术水平是做不到的。既然延迟无法消除,如果能知道这个延迟的时间,也可以通过计算消除延迟的影响。
*** 中的数据包传输大致如下:
这些值如下所示:
C1:客户端发出请求的当地时间。
C2:客户端接收返回的本地时间。
S1:时间服务器收到请求时的服务器时间。
S2:时间服务器发送响应时的服务器时间。
SC1:客户端发出请求时的服务器时间。
SC2:客户端接收返回的服务器时间。
CS1:时间服务器收到请求时的本地时间。
CS2:时间服务器响应时的本地时间。
我们的目的现在看来很简单,那就是在我们收到回报时校准C2到SC2的当地时间。首先,应该明确的是,C2和SC2不想等待,否则他们不需要在时间相同时进行校准。
首先,我们在本地知道的信息是C2 C1,这可以让服务器在返回的结果中告诉我们S2 S1。此外,我们假设 *** 中的延迟基本上是固定的,即S1-C1=C2-S2。
好了,现在已经成功转化为一道数学题了。是不是突然觉得轻松多了?步骤如下:
Da = (C2-C1)-(S2-S1) #总延误时间

D = da/2 #单次延迟时间
SC1 = S1 d
SC2 = SC1 + (C2 - C1)
怎么样?它巧妙地消除了 *** 延迟。
以上是ntp协议进行时间同步的内容。然而,这样的同步时间也有误差。首先,假设往返 *** 延迟相同。如果延迟不对称,同步结果将会不准确。而且协议运行在应用层,物理层到应用层的延迟也会影响最终的结果。
在实际编程中,我们经常会编写这样的代码:
$t1=time();//dosometing...$t2=time();
如果,在获得$t1变量后,发生时间同步,那么$t2可能小于$t1,是不是很诡异?不过好在有不同的同步方式供我们选择。以下测试是在Ubuntu系统上进行的。
Ntp:时间平滑过度,保证本地时间增加,减少本地和远程的时差。
Ntpdate:立即同步,以上$t2小于$t1的场景可能会出现在这种功能情况下。
但是在我的服务器Ubuntu 18上,默认不再使用ntp工具,而是使用timedatectl,其内部协议是一样的。具体时间请参考官网说明:https://ubuntu.com/server/docs/network-ntp