Time 分布式时间同步与web应用

Time 分布式时间同步与web应用,time,synchronization,distributed,Time,Synchronization,Distributed,我目前正在尝试构建一个应用程序,该应用程序本质上需要跨服务器和每个客户端进行良好的时间同步。对于我的应用程序,有一些替代设计可以消除这种同步需求,但当我的应用程序不存在时,它很快就会开始变得糟糕 如果我遗漏了什么,我的基本问题是:在同一时刻在多个地点触发事件。据我所知,唯一的方法就是进行时间同步,但我可能错了。我尝试过以不同的方式对问题进行建模,但结果都是a)一个糟糕的应用程序,或者b)需要时间同步 假设我真的需要同步时间 我的应用程序是建立在谷歌AppEngine上的。虽然AppEngine无

我目前正在尝试构建一个应用程序,该应用程序本质上需要跨服务器和每个客户端进行良好的时间同步。对于我的应用程序,有一些替代设计可以消除这种同步需求,但当我的应用程序不存在时,它很快就会开始变得糟糕

如果我遗漏了什么,我的基本问题是:在同一时刻在多个地点触发事件。据我所知,唯一的方法就是进行时间同步,但我可能错了。我尝试过以不同的方式对问题进行建模,但结果都是a)一个糟糕的应用程序,或者b)需要时间同步

假设我真的需要同步时间

我的应用程序是建立在谷歌AppEngine上的。虽然AppEngine无法保证其服务器之间的时间同步状态,但通常情况下,在几秒钟的时间内(即优于NTP),时间同步效果相当好,但有时会很差,比如说,10秒钟的时间不同步。我的应用程序可以处理2-3秒的不同步,但就用户体验而言,10秒是不可能的。因此,基本上,我选择的服务器平台并没有提供非常可靠的时间概念

我的应用程序的客户端部分是用JavaScript编写的。同样,我们也遇到了客户也没有可靠的时间概念的情况。我没有做任何测量,但我完全希望我的一些最终用户的计算机时钟设置为1901、1970、2024等等。因此,基本上,我的客户端平台没有提供可靠的时间概念

这个问题开始让我有点发疯了。到目前为止,我认为最好的办法是在HTTP之上实现NTP(这并不像听起来那么疯狂)。这将通过在互联网的不同部分调试2或3台服务器来实现,并使用传统方法(PTP、NTP)尝试确保它们的同步至少在数百毫秒左右

然后,我将创建一个JavaScript类,该类使用这些HTTP时间源(以及XMLHTTPRequest中提供的相关往返信息)实现NTP交叉算法

正如你所知道的,这个解决方案也很浪费时间。它不仅非常复杂,而且只解决了问题的一半,即给客户一个关于当前时间的好概念。然后,我不得不在服务器上妥协,要么允许客户端在发出请求时根据他们告诉服务器当前时间(大安全性没有,但我可以减轻一些更明显的滥用),要么让服务器向我的一个神奇的HTTP over NTP服务器发出单个请求,希望这个请求能尽快完成

这些解决方案都很糟糕,我迷路了


提醒:我希望一组web浏览器(可能多达100个或更多)能够在完全相同的时间触发事件。

时间同步很难做到正确,在我看来是错误的。您需要一个事件系统,它可以在每次调度事件时通知注册的观察者()。将同时(或尽可能接近)通知所有观察员,从而消除时间同步的需要


为了适应延迟,应该向浏览器发送事件调度的时间戳,并且浏览器的等待时间应该比您预期的最大延迟时间稍长。这样,所有浏览器上的所有事件都将同时启动。

在我看来,您似乎需要在许多不同的地方收听来自服务器的广播事件。既然您可以接受2-3秒的变化,那么您可以将所有客户机放入长寿命comet样式的请求中,然后从服务器获得响应?在我看来,客户不需要这样处理时间

您可以使用ajax来实现这一点,因此在等待新数据时可以避免任何客户端锁定


我可能完全遗漏了一些东西。

让我总结一下,以确保我理解这个问题

您有一个具有客户端和服务器组件的应用程序。有多个服务器,每个服务器都可以为许多(数百)个客户端提供服务。服务器之间或多或少是同步的;客户不是。您希望大量客户机在几乎相同的时间执行相同的事件,而不管他们最初连接到哪个服务器

假设我或多或少准确地描述了情况:

您是否可以让服务器为每个客户端保持特定的状态(例如连接的初始时间--服务器时间),并且当需要发生的事件的时间已知时,使用一条消息通知客户端,该消息包含在触发事件之前需要经过的起始值之后的毫秒数

举例说明:

client A connects to server S at time t0 = 0 client B connects to server S at time t1 = 120 server S decides an event needs to happen at time t3 = 500 server S sends a message to A: S->A : {eventName, 500} server S sends a message to B: S->B : {eventName, 380} 客户端A在时间t0=0时连接到服务器S 客户机B在t1=120时连接到服务器S 服务器S决定事件需要在t3=500时发生 服务器S向以下服务器发送消息: S->A:{eventName,500} 服务器S向B发送消息: S->B:{eventName,380}
这完全不依赖于客户的时间;这取决于客户端在合理的短时间内(一次会话)跟踪时间的能力。

如果您可以假设时钟是合理稳定的,也就是说,它们设置错误,但运行速度或多或少是正确的

让服务器从单个定义的源(例如,您的一台服务器、数据库服务器或其他)获取其偏移量

然后让每个客户机计算它与服务器的偏移量(如果您想要更精确的话,可能会出现往返复杂情况)

存储该值,然后在每个客户机上计算组合偏移量,以便在正确的时间触发事件

(client-time-to-trigger-event) = (scheduled-time) + (client-to-server-difference) + (server-to-reference-difference)

谷歌找到了将时间定义为绝对时间的方法。听起来