Распределенная синхронизация времени и веб-приложений - PullRequest
9 голосов
/ 11 января 2009

В настоящее время я пытаюсь создать приложение, которое по своей природе нуждается в хорошей синхронизации времени на сервере и на каждом клиенте. Существуют альтернативные схемы для моего приложения, которые могут покончить с этой необходимостью синхронизации, но мое приложение быстро начинает сосать, когда его нет.

В случае, если я что-то упустил, моя основная проблема заключается в следующем: запуск события в нескольких местах в один и тот же момент. Насколько я могу судить, единственный способ сделать это требует некоторой синхронизации времени, но я могу ошибаться. Я пытался смоделировать проблему по-другому, но все возвращается к а) плохому приложению или б) необходимости синхронизации времени.

Давайте предположим, что мне действительно нужно синхронизированное время.

Мое приложение построено на Google AppEngine. Хотя AppEngine не дает никаких гарантий о состоянии синхронизации времени на своих серверах, обычно она довольно хорошая, порядка нескольких секунд (т.е. лучше, чем NTP), однако иногда она плохо отстой, скажем, порядка 10 секунд. синхронизации Мое приложение может обрабатывать 2-3 секунды не синхронизировано, но 10 секунд не может быть и речи в отношении пользовательского опыта. Таким образом, в основном, выбранная мной серверная платформа не обеспечивает очень надежную концепцию времени.

Клиентская часть моего приложения написана на JavaScript. Опять же, у нас ситуация, когда у клиента нет надежного представления о времени. Я не делал никаких измерений, но я полностью ожидаю, что у некоторых из моих будущих пользователей будут компьютерные часы, которые установлены на 1901, 1970, 2024 и так далее. В общем, моя клиентская платформа не обеспечивает надежную концепцию времени.

Эта проблема начинает сводить меня с ума. Пока что лучшее, что я могу сделать, это реализовать что-то вроде NTP поверх HTTP (это не так безумно, как может показаться). Это сработает, введя в эксплуатацию 2 или 3 сервера в разных частях Интернета и используя традиционные средства (PTP, NTP), чтобы убедиться, что их синхронизация по крайней мере порядка сотен миллисекунд.

Затем я бы создал класс JavaScript, который реализовал алгоритм пересечения NTP с использованием этих источников времени HTTP (и связанной с этим информации о приеме-передаче, доступной из XMLHTTPRequest).

Как вы можете сказать, это решение также отстой. Это не только ужасно сложно, но и решает только половину проблемы, а именно дает клиентам хорошее представление о текущем времени. Затем я должен пойти на компромисс на сервере, либо разрешив клиентам сообщать серверу текущее время в соответствии с ними, когда они делают запрос (большая безопасность - нет, но я могу смягчить некоторые из наиболее очевидных злоупотреблений этим), или когда сервер делает один запрос к одному из моих волшебных серверов HTTP-over-NTP и надеется, что этот запрос будет выполнен достаточно быстро.

Все эти решения - отстой, и я потерялся.

Напоминание: я хочу, чтобы несколько веб-браузеров, возможно, до 100 или более, могли запускать событие в одно и то же время.

Ответы [ 5 ]

2 голосов
/ 11 января 2009

Мне кажется, что вам нужно прослушивать трансляцию с сервера во многих разных местах. Так как вы можете принимать 2-3 секунды вариации, вы можете просто поместить всех своих клиентов в долгоживущие запросы в стиле комет и просто получить ответ от сервера? Похоже, что клиентам вообще не нужно было бы иметь дело со временем?

Вы можете использовать ajax для этого, так что вы будете избегать любых блокировок на стороне клиента, ожидая новых данных.

Возможно, я что-то здесь упускаю.

2 голосов
/ 11 января 2009

Позвольте мне подвести итог, чтобы убедиться, что я понимаю вопрос.

У вас есть приложение с клиентским и серверным компонентами. Существует несколько серверов, каждый из которых может обслуживать множество (сотни) клиентов. Серверы более или менее синхронизированы друг с другом; клиенты не. Вы хотите, чтобы большое количество клиентов выполняло одно и то же событие примерно в одно и то же время, независимо от того, к какому серверу они подключились изначально.

Предполагая, что я описал ситуацию более или менее точно:

Возможно, серверы сохраняют определенное состояние для каждого клиента (например, начальное время соединения - время сервера), а когда известно время события, которое должно произойти, уведомите клиента сообщением, содержащим количество миллисекунд после начального значения, которое должно пройти до запуска события?

Для иллюстрации:

   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}

Это вовсе не зависит от времени клиента; просто на способность клиента отслеживать время в течение некоторого достаточно короткого периода (один сеанс).

1 голос
/ 11 января 2009

Если вы можете предположить, что часы достаточно стабильны, то есть они установлены неправильно, но тикают с более или менее правильной скоростью.

Пусть серверы получат свое смещение из одного определенного источника (например, один из ваших серверов или сервер базы данных или что-то еще).

Затем пусть каждый клиент вычислит свое смещение от своего сервера (возможные сложности в обоих направлениях, если вам нужна большая точность).

Сохраните это, затем вы скомбинируете смещение на каждом клиенте, чтобы вызвать событие в нужное время.

(client-time-to-trigger-event) = (scheduled-time) + (client-to-server-difference) + (server-to-reference-difference)
1 голос
/ 11 января 2009

Синхронизация времени очень трудно сделать правильно, и, на мой взгляд, это неправильный путь. Вам нужна система событий, которая может уведомлять зарегистрированных наблюдателей каждый раз, когда событие отправляется ( шаблон наблюдателя ). Все наблюдатели будут уведомлены одновременно (или как можно ближе к этому), устраняя необходимость синхронизации времени.

Чтобы учесть задержку, браузер должен отправить метку времени отправки события, и он должен ждать немного дольше, чем ожидаемая максимальная задержка. Таким образом, все события будут запущены одновременно во всех браузерах.

0 голосов
/ 28 марта 2014

Google нашел способ определить время как абсолютное. Для физика это звучит еретично и в отношении общей теории относительности: время течет с разной скоростью в зависимости от вашего положения в пространстве и времени, на Земле, во Вселенной ...

Возможно, вы захотите взглянуть на базу данных Google Spanner: http://en.wikipedia.org/wiki/Spanner_(database)

Полагаю, сейчас он используется Google и будет доступен через Google Cloud Platform.

...