Подтвердить что ты не робот

Самоорганизующиеся приложения

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

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

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

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

Я создал прототип в С#, который обменивается данными и пытается реплицировать данные, но часть переговоров (особенно в сочетании с отказом клиента).

Сначала я подумал, что сделал ZeroConf (он же Bonjour). Но это только объявляет о доступных сетевых сервисах.

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

  • Есть ли образец, который уже реализует то, что я описал выше?
  • Если да, есть ли для этого доступная библиотека .NET(или даже родная)?
  • Каковы хорошие способы согласования роли сервера среди клиентов?
4b9b3361

Ответ 1

Итак, в настоящее время у вас есть система, в которой каждый клиент в локальной сети объявит себя через UDP для остальной части локальной сети. Одно из клиентских приложений - это "сервер" и обладает некоторыми дополнительными полномочиями управления и контроля над самим клиентом.

Это не новая идея. Вы хотите добавить дополнительные разговоры во время первоначальной связи "здесь я". Когда новый клиент кричит "вот я" на всю локальную сеть, если есть сервер, сервер должен сказать "Добро пожаловать, я сервер", а новое клиентское приложение теперь знает, какой клиент действует как сервер. Все остальные клиенты должны, вероятно, сказать "привет". Если сервер не существует, новый клиент должен сначала повторить "привет" (в конце концов, это UDP, вы должны ожидать, что некоторые сообщения не будут получены), и если никто не отвечает, этот новый клиент является единственным на сети и является "сервером" по умолчанию. Если есть другие, но никто не претендует на роль сервера, клиенты могут "обсудить между собой", чтобы определить новый сервер.

В дополнение к этому, серверная копия должна периодически (возможно, каждые 3-5 секунд) кричать "Я все еще здесь" для всех; это известно как сообщение "heartbeat" и является очень распространенной альтернативой методу проверки "ping" в двух направлениях.

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

Теперь клиенты, "обсуждающие между собой", могут быть такими же простыми или сложными, как вам нравится. Самый простой был бы для того, что клиент говорит "ОК, я сервер сейчас", чтобы стать сервером. Вероятно, вам придется включить какое-то время в сообщение, чтобы, если другой компьютер говорит, что в то же время клиенты могут сказать: "Хорошо клиент 15 сказал это сначала, чтобы мы пошли с ним". Клиенты могут "голосовать"; каждый клиент будет говорить со всеми другими, чтобы определить номинальную задержку между этим клиентом и всеми остальными, и этот клиент будет "голосовать" за соединение с низкой задержкой (ни один клиент не может голосовать за себя, если только он не обнаруживает его только один). Большинство голосов побеждает.

Или сервер может, как часть своего сообщения "heartbeat" , сказать "если я спускаюсь, мой преемник - клиент X"; и если пропущено сердцебиение, и последующие "вы все еще там, серверные" сообщения от клиентов не отвечают, клиенты могут сказать: "Король мертв! Да здравствует King Client X!".

Понимать, что по необходимости этот уровень управления в рамках всей клиентской системы при выборе "авторитетного" клиента, чтобы стать сервером, значительно увеличит сложность клиентских коммуникаций. Кроме того, в то время как ваше использование протокола UDP поддается быстрой связи, сообщения UDP сталкиваются ВСЕ ВРЕМЯ; если вы говорите, когда разговаривает другой человек, ваши сообщения сталкиваются. Поэтому я бы рекомендовал использовать TCP вместо UDP для большей коммуникации в этом программном обеспечении, в котором необходимо, чтобы конкретный клиент был услышан. Это любой прямой опрос клиента ( "вы все еще там, сервер?" ), Независимо от того, какой процесс вы используете, чтобы клиенты решали, кем является новый сервер и т.д. И т.д.

Ответ 2

Выбор сервера среди группы машин, независимо от того, являются ли эти машины клиентами или нет, является чрезвычайно нетривиальной проблемой. Он называл выборы лидеров. Основная работа, которую вы должны прочитать, - это Лесли Лампорт "Парламент времени" , в котором описывается протокол Paxos. Paxos использует Google для разработки системы под названием Chubby, которая служит той цели, которую вы описываете.

Тем не менее, вы должны, вероятно, посмотреть на систему типа Apache ZooKeeper, которая представляет собой реализацию с открытым исходным кодом (хотя и Java) распределенного лидерские выборы и, более широко, распределенное управление блокировками, которое было тщательно протестировано под большой нагрузкой. Hadoop распределенная платформа хранения данных и вычислений, и в частности HBase, распределенная база данных, которая работает на Hadoop, сильно использует ZooKeeper, чтобы решить, "кто отвечает" среди группы серверов. Таким образом, любой из них может пойти вниз, а другие сами решат, кто возьмет на себя эту работу.

Как я упоминал ранее, выборы лидеров чреваты ошибкой. Это очень сложно. Я реализовал paxos "для удовольствия" полдюжины раз в С#, и все мои реализации имеют ошибки в них.

Ответ 3

Зачем вам вообще нужно обсуждать роль сервера? Подумайте об этом на секунду. Если каждый "клиент" может обрабатывать обязанности "сервера" для работы, инициированной на клиенте, то все они обрабатывают как клиент, так и сервер. Тогда единственная проблема заключается в согласовании репликации сохраняющегося состояния между клиентами и обработке concurrency, когда два клиента обрабатывают один и тот же бит состояния (самая сложная часть, с моей точки зрения, будет предупреждать, что состояние других клиентов было изменено, когда один клиент "" сохраняет" данные и другие клиенты, работающие над состоянием, открывают метод разрешения конфликтов - может быть, не проблема, если последняя всегда побеждает, но это редко).

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

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