Как записать относительное время между компьютерами?

StackOverflow https://stackoverflow.com/questions/827473

  •  05-07-2019
  •  | 
  •  

Вопрос

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

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

Итак, с каждой машины я получаю журнал, полный этих

public class Activity {
    DateTime TimeOccurred { get; set; }
    string Description { get; set; }
}

Всякий раз, когда (1) или (2) происходит выше, я добавляю действие в журнал и транслирую его на другие машины, которые добавляют это же действие в свой журнал, причем TranslatedTime является их собственным временем:

public class TimeSynchronization : Activity {
    string SourceMachine { get; set; }
    DateTime TranslatedTime { get; set; }
}

Таким образом, машина A будет иметь (по порядку):

TimeSynchronization "started" at 3:00 am.
Activity "asked a question" at 3:05 am.
TimeSynchronization from machine B at 3:05 am.
TimeSynchronization "clock changed" at 3:03 am.
Activity "received an answer" at 3:04 am.

И машина B будет иметь (по порядку):

TimeSynchronization "started" at 3:05 am.
TimeSynchronization "clock changed" at 3:06

Поэтому мне нужно восстановить тот же порядок и время этих событий, например:

On machine A: TimeSynchronization "started" at 0:00
On machine A: Activity "asked a question" at 0:05
On machine B: TimeSynchronization "started" at 0:05
On machine A: TimeSychronization from machine B at 0:05
On machine A: TimeSynchronization "clock changed" at 0:06
On machine B: TimeSynchronization "clock changed" at 0:06
On machine A: Activity "received an answer" at 0:07

Как лучше всего взять List<Activity> с каждого компьютера и объединить его в один список с событиями по порядку?

Это было полезно?

Решение

Если две машины соединены через сеть, ваша программа может спросить другую машину, который час. Таким образом, ваша программа на компьютере A может запросить время на A и B, а затем войти в систему оба раза.

Вы упоминаете, что время может меняться в течение дня (предположительно, пользователь изменил время). Вы можете обнаружить это с помощью события Win32.TimeChanged.

Другие советы

Атомное время и веб-сервис, который предоставит его вам. Это то, что вам нужно. Реалистичная? Без понятия. Но по крайней мере вам не нужно беспокоиться о том, что n компьютеров пытаются синхронизировать свои часы.

Похоже, они хотят, чтобы вы интуитивно подходили к распределенным транзакциям

Кроме того, ознакомьтесь с сетевым протоколом времени :

  

NTP - это протокол, разработанный для   синхронизировать часы компьютеров   по сети.

Я думаю, что вы хотите записать все в UTC (универсальное время). Это позволит записывать время по отношению к общему моменту времени и делает сравнение дат / времени очень простым. чтобы отобразить их по местному времени, вы просто определяете смещение и вычисляете разницу от времени UTC до местного. например на восточном побережье - UTC-5, поэтому, если время UTC - 17:00, местное время в Нью-Йорке - 12:00, а в Далласе - UTC-6, то есть 11:00 утра.

Итак, если у вас есть событие в 11:10 утра в Далласе, его UTC время 17:10, а событие в Нью-Йорке в 12:05 вечера 17:05 UTC, вы знаете, что событие в Нью-Йорке произошло первым , но если вы сравните время, это не будет так.

UTC также обладает тем преимуществом, что он всегда представляет все 24 часа в сутки, так что осенью, когда вы выходите в нерабочее время, вы не получаете 2 комплекта по 2 часа ночи или 3 часа ночи и не теряете часы во время весны. вперед, чтобы перейти на экономию времени.

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

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

Если вам нужна очень точная синхронизация часов между компьютерами, используйте GPS.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top