Как записать относительное время между компьютерами?
-
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.