Синхронизация (часов) между двумя удаленными компьютерами - PullRequest
14 голосов
/ 23 декабря 2008

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

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

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

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

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

Обновление: Позвольте мне просто добавить, что меня не интересует фактическая синхронизация системных часов двух компьютеров - я предполагаю, что операционная система справится с этим в большинстве случаев. Это всего лишь вопрос о том, как обеспечить, чтобы два экземпляра приложения использовали синхронизированное время, хотя я полагаю, что в наше время системные часы почти наверняка будут синхронизированы с какой-то очень маленькой дельтой.

Ответы [ 9 ]

18 голосов
/ 23 декабря 2008

Полагаться на NTP для вашего приложения, как рекомендовали другие, - это легко. Правильный подход заключается в использовании алгоритма распределенной синхронизации часов Lamport. Это объясняется в его классической статье 1978 года Время, часы и порядок событий в распределенной системе .

8 голосов
/ 23 декабря 2008

Посмотрите на спецификацию " Network Time Protocol " (NTP).

5 голосов
/ 07 марта 2013

Вы можете попробовать PTP. Протокол точного времени (PTP) - это протокол, используемый для синхронизации часов по всей компьютерной сети. В локальной сети он достигает тактовой частоты в субмикросекундном диапазоне, что делает его пригодным для систем измерения и управления. http://en.wikipedia.org/wiki/Precision_Time_Protocol

3 голосов
/ 31 октября 2009

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

1) Недостаточно компьютерных знаний для настройки синхронизации по времени ntp

2) Установите часы своего компьютера на домашние часы или часы мобильного телефона, которые являются неправильными

3) В Windows XP случайно отключите синхронизацию времени ntp и не знаете, как включить его снова, или неправильно установите дату на компьютере, в этом случае Windows ntp не работает

4) Аккумуляторная батарея компьютера разрядилась, поэтому компьютер всегда запускается в 1970 году!

5) Пользователь вывозит свой ноутбук за границу и временно устанавливает часы ноутбука на местное время, но не меняет часовой пояс, поэтому теперь компьютер вернет неправильное время utc !!!

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

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

Я предлагаю эту схему, которая берет некоторые идеи из работы cron-заданий, я был бы рад, если бы кто-нибудь мог предложить улучшения этой идеи.

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

2) После этого добавляется время, оставшееся от системных часов, для поддержания времени. Если требования строгие, вам может потребоваться повторять синхронизацию ntp с интервалами.

3) Затем приложение просматривает список будущих заданий, которые необходимо выполнить в срок. Нужно знать самую раннюю работу.

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

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

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

Улучшения к идее:

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

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

3) Чтобы время вызова Soap получало время, запишите, когда мыло отправлено и когда получен ответ. Если время выполнения заказа слишком велико, вы не можете рассчитывать на это время, и вам может потребоваться повторить вызов, или вы можете пойти на компромисс. Например, если Soap сообщает, что часы компьютера работают на 5 минут быстрее, а сам вызов Soap занял минуту, чтобы ответить, то можно с уверенностью сказать, что часы компьютера работают как минимум на 4 минуты.

3 голосов
/ 23 декабря 2008

Вместо того, чтобы писать код для синхронизации часов, разве нельзя было бы просто запустить клиент ntp на обеих машинах?

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

3 голосов
/ 23 декабря 2008

Синхронизируйте их с NTP Сетевым протоколом времени.

На какой ты платформе?

С NTP вы можете синхронизировать время ваших компьютеров с атомными часами и использовать официальное время мира.

2 голосов
/ 23 декабря 2008

Одна вещь, которую мы делаем, - это, по сути, разгрузка всех операций синхронизации на хост-машину. Например, если у вас есть 20 серверов, которые все совместно используют БД, используйте время БД. Если у вас есть центральный сервер и миллион клиентских машин, клиентские машины не должны отвечать за синхронизацию; сделайте всю свою синхронизацию на стороне сервера. В действительно «распределенной» среде, такой как P2P-сеть или что-то подобное, используйте машину, которая самым непосредственным образом «владеет» данным ресурсом (реальный ПК - файл, который вы хотите записать) для синхронизации / контроля доступа к файлу.

0 голосов
/ 16 июля 2011

Не используйте NTP. NTP только для получения даты / времени.

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

Для приложений, которые имеют прямую связь, совместно используют ресурс, используют часы лампового или векторного часов, как сказал Диомидис. Часы Lamport прекрасно работают для достижения частичного порядка между событиями, а векторные часы хороши, когда вам нужно идентифицировать параллельные события.

0 голосов
/ 23 декабря 2008

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

...