【问题标题】:Distributed time synchronization and web applications分布式时间同步和 Web 应用程序
【发布时间】:2009-01-11 05:49:47
【问题描述】:

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

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

假设我真的真的需要同步时间。

我的应用程序是基于 Google AppEngine 构建的。虽然 AppEngine 不保证其服务器之间的时间同步状态,但通常它非常好,大约几秒钟(即比 NTP 好),但有时它很糟糕,比如说,大约 10 秒的同步。我的应用程序可以处理 2-3 秒的不同步,但就用户体验而言,10 秒是不可能的。所以基本上,我选择的服务器平台并没有提供非常可靠的时间概念。

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

这个问题开始让我有点抓狂。到目前为止,我能想到的最好的事情就是在 HTTP 之上实现类似 NTP 的东西(这并不像听起来那么疯狂)。这将通过在 Internet 的不同部分调试 2 或 3 台服务器来实现,并使用传统方式(PTP、NTP)来尝试确保它们的同步至少在数百毫秒的数量级上。

然后,我将创建一个 JavaScript 类,该类使用这些 HTTP 时间源(以及可从 XMLHTTPRequest 获得的相关往返信息)实现 NTP 交集算法。

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

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

提醒:我想要一堆网络浏览器,希望多达 100 个或更多,能够同时触发一个事件。

【问题讨论】:

    标签: time synchronization distributed


    【解决方案1】:

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

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

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

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

    举例说明:

    客户端 A 在时间 t0 = 0 连接到服务器 S 客户端 B 在时间 t1 = 120 连接到服务器 S 服务器 S 决定一个事件需要在时间 t3 = 500 发生 服务器 S 向 A 发送消息: S->A : {事件名称, 500} 服务器 S 向 B 发送消息: S->B:{事件名称,380}

    这根本不依赖于客户端时间;仅取决于客户在相当短的时间内(单个会话)跟踪时间的能力。

    【讨论】:

      【解决方案2】:

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

      您可以使用 ajax 来执行此操作,因此您可以在等待新数据时避免任何客户端锁定。

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

      【讨论】:

        【解决方案3】:

        如果您可以假设时钟相当稳定 - 即它们设置错误,但以或多或少正确的速率滴答作响。

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

        然后让每个客户端计算它与服务器的偏移量(如果您想要更高的准确性,可能会出现往返复杂性)。

        存储它,然后您在每个客户端上的组合偏移量以在正确的时间触发事件。

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

        【讨论】:

          【解决方案4】:

          时间同步很难做到正确,我认为这是错误的方法。您需要一个事件系统,它可以在每次调度事件时通知已注册的观察者 (observer pattern)。所有观察者将同时(或尽可能接近)收到通知,无需时间同步。

          为了适应延迟,应该向浏览器发送事件分派的时间戳,并且它的等待时间应该比您预期的最大延迟时间长一点。这样一来,所有事件都会在所有浏览器上同时触发。

          【讨论】:

          • 嗨 Eran,迁移到事件系统只会将时间问题转移到其他地方,即网络。我可以使用适时过期的长期 HTTP 请求,但这些请求的延迟会根据 HTTP 客户端与服务器的距离而变化。
          • 不,事件系统不是基于时间的 - 无论事件发生的时间如何,都会通知所有观察者。如果您知道延迟,则以您期望的最大延迟的等待期发出事件,并让浏览器计算等待期还剩多少时间
          【解决方案5】:

          Google 找到了将时间定义为绝对值的方法。对于物理学家和广义相对论而言,这听起来很异端:时间以不同的速度流动,具体取决于您在空间和时间、地球、宇宙中的位置......

          您可能想看看 Google Spanner 数据库:http://en.wikipedia.org/wiki/Spanner_(database)

          我猜它现在已被 Google 使用,并将通过 Google Cloud Platform 提供。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-04-07
            • 2011-06-30
            • 1970-01-01
            • 2020-02-26
            • 2012-09-11
            • 1970-01-01
            • 1970-01-01
            • 2010-09-18
            相关资源
            最近更新 更多