1.问题来源:
设备A想要给设备B同步时间,最直接的办法,A发送当前时间到B,但这个问题会带来一些问题。
1.1 例子:
设备A(后面叫Master设备)现在拥有准确时间9点整, 设备B(后面叫Slave设备)拥有错误时间10点整。 那么时间更新的流程是这样: slave收到master的时间,并且更新slave的时间(不考虑传输延迟更新时间的流程如下)
1.1.1 假设传输延迟为0ms:
那么slave收到master发送时间的时刻为9点,则slave更新时间为9点,那么master和slave的时间误差为0
1.1.2 假设传输延迟为10min:
那么slave收到master发送时间的时刻为9点1分,则slave更新时间为9点1分,那么master和slave的时间误差为10min
问题:时间同步必须考虑传输延迟问题,否则时间到底更新的准不准也没法确定。
2.如何解决传输延迟:
2.1 延迟的测量:
我们在上帝视角可以知道这个传输延迟是多少。但仔细一想,作为slave端,是不知道收到的时间戳所带的误差是多少。
2.1.1 ping的测量:
上面的图是一个ping的结果,其中time表示的值表示从发送 ICMP 请求到收到响应的时间,单位是毫秒(ms)。
2.1.2 延迟的计算:
这个类比到我们的问题中,就是master发送报文到slave, slave回复master。
然后这个来回时间加起来是time这么久。这个timeOfst= Master到slave的传输延迟 + slave到Master的传输延迟。
假定 Master到slave的传输延迟 == slave到Master的传输延迟
那么 传输延迟 == timeOfst / 2;
2.1.3 计算出来的误差有多大呢?
如果timeOfst== 100ms, 那么传输延迟=50ms, 因为单向的延迟为0~100ms, 那么(0~100ms) - 50ms 表示误差在-50ms ~ 50ms之间。代表更新后的时间误差最大为50ms。要么快50ms,要么慢50ms)
3.利用计算得到的延迟更新时间:
如下图,slave去ping Master,最后得到延迟为timeOfst/2, 用这个timeOfst/2 + 收到的Master时间戳来更新slave时间。
4.总结:
总之:正确的同步时间,就是slave端的正确时间 = master时间 + 传输延时。