- 看懂原理,重新实现NTP
- 前端GUI可复用,看情况加一点别的展示的东西
- 分析NTP的问题 + 提出改进方案
- 选做部分
- 实现解决方案(提出解决方案的人来做)
- 调研其他项目 / 同步时间方案
原理 / 技术实现
通信协议:响应-应答
核心行为
- 创建本地通信资源
- 创建socket,配置其在非阻塞模式下工作
- DNS解析器将服务器域名解析为IP地址
- 与该IP地址对应的NTP服务器建立socket通信
性能与鲁棒性
- 通信需要在较短时间内返回结果
- 通信异常处理(服务器无响应等)
改进 / 测试
- 时间同步是直接使用的「服务端发送的时间」(即T3)进行同步,而非计算offset之后同步
- 用T4 + θ代替当前时间
- 对比调整前后的时间差
将socket的最大接收阻塞时间调整为动态的,对比不同情况的效果

- 动态切换NTP服务器域名:
- 按照服务器域名列表顺序进行请求,当DNS解析失败 / 服务器多次超时无响应时则将该服务器域名置于列表末尾,然后对下一个域名进行请求
- 若所有服务器都有故障则报错
问题分析与解决方案
- 时间精度
- NTP协议是基于 往返路由延时是对称的 假设进行的时钟同步,在offset的计算中假设d1 = d2 = RTT / 2,性能会受网络延迟和不稳定性的影响
- 在网络传输层次上,offset的最大误差为 ±RTT / 2
- 可能的解决方案:在对时间的顺序性有高要求的功能上,可以根据NTP返回的时间以及误差范围,使用时间置信区间代替一个具体的时间戳,例如:判定一个系统处于0.3s和0.4s之间的概率是95%。
- 案例:Google的Spanner系统的TrueTime提供的api,会返回两个值 [earliest, latest],表示可能的最早和最晚的时间。
- Spanner实现事务id的方式:如果两个置信区间 A = [Aearliest, Alatest] 和 B = [Bearliest, Blatest] 没有交集 (Aearliest < Alatest < Bearliest < Blatest) ,那么事件A先于事件B;如果有交集,那么无法判断顺序。为了能够反映逻辑,确保读取事务有足够的延迟,Spanner会等待一个置信区间的时间后才提交事务,因为置信区间不会重叠。
- 局域网络时延较大:时间戳一般都是在应用层加盖,操作系统内核处理存在延时。
- 发/收NTP包时间戳应尽量接近主机真实发/收包时刻。修改网卡驱动程序,在网卡驱动程序处记录NTP包发/收时间戳,可消除操作系统内核处理延时不确定而引入的误差

- 故障
- 当发送失败 / NTP服务器无响应时,应当自适应地处理和切换NTP服务器
- 设置请求数上限( := 3),请求数超过上限后 静默切换到下一个NTP服务器再次进行请求,同时记录请求失败的服务器个数
- 次数超过列表服务器总数时放弃同步并输出错误信息
- 实现细节:根据发出请求后的结果码进行判断,若为无响应则记录此NTP服务器响应失败次数,超过人为设定的请求数上限时则将此服务器记为失效服务器;若为DNS解析IP地址失败则直接换到下一个NTP服务器。同时记录总失效服务器数,≥服务器列表的size则弹出警告窗口,放弃同步。
- 重要性:分布式系统的时间一致性直接影响数据的正确性和系统的协同性
- 确保事件的顺序性
- 每个节点可能独立产生日志、事件或记录。时间同步能帮助各节点按时间顺序记录事件,确保事件的顺序一致性。
- 如果时间不同步,事件顺序可能被错误地记录,比如写入操作可能在读取之后发生,从而影响事务的正确性。
- 数据复制、分片等场景:时间误差会导致不同节点在合并数据或判断最新数据时出现偏差
- 各节点需要判断数据的最新状态。如果时间不同步,可能导致版本控制错误,从而引发数据冲突或一致性问题。