Вопрос

Я знаю, что с Network Load Balancing и Failover Clusteringмы можем сделать пассивные услуги высокодоступный.Но как насчет активные приложения?

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

  1. Запустите его на одной машине.Проблема:если этот экземпляр упадет, содержимое не будет восстановлено
  2. Запустите его на каждой машине кластера.Проблема:содержимое будет извлечено несколько раз
  3. Имейте его на каждой машине кластера, но запускайте только на одной из них.Каждый экземпляр должен будет проверить какой-то общий ресурс, чтобы решить, настала его очередь выполнять задачу или нет.

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

Является ли это лучшим решением?Как люди обычно это делают?

Кстати, это приложение C # .NET WCF, работающее на Windows Server 2008

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

Решение

Для таких проблем они изобрели очереди сообщений. Представьте, что случай, когда ваши кластерные приложения все слушают очередь сообщений (кластеризованный сам :-)). В какой-то момент один экземпляр получает вашу исходную команду для загрузки вашего внешнего ресурса. Если успешно, ваш экземпляр вымывает сообщение и вместо этого он публикует еще один для более позднего времени выполнения, который равен «время выполнения» + «Интервал». Но в случае, если экземпляр умирает во время обработки, это не проблема. Сообщение возвращено в очередь (после периода времени ожидания), а какой-то другой экземпляр может забрать его. Немного транзакций, немного сообщений очередей

Я нахожусь на стороне Java EE из мира, поэтому может помочь вам с деталями кодирования

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

Я когда-то реализовал что-то подобное, используя ваше решение № 3.

Создать таблицу, называемую что-то вроде resource_lock, с столбцом (например, locking_key) Это будет содержать блокирующий ключ.

Затем на каждом интервале весь экземпляр вашего приложения будет:

  1. Запустить запрос, какupdate resource_lock set resource_key = 1 where resource_key is null'. (Вы можете, конечно, также вставить идентификатор, специфичный сервером, временем времени и т. Д.)
  2. Если 0 строки обновлены: ничего не сделайте - еще один экземпляр приложения уже выходит на ресурс.
  3. Если 1 ряд обновляется: извлеките ресурс и установите locking_key вернуться к null.

Есть два преимущества с этим:

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

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

  • Задача должна успешно завершить?
  • Если задача не завершится успешно, «кто» должен знать, и какие виды действий необходимо выполнить?
  • Как поведение, если задача не завершена, когда придет время снова запускать задачу? Должен ли он работать или нет?
  • Насколько важно, чтобы рабочие места запускаются по указанному интервалу? Если интервал каждые 5 минут он должен быть каждые 5 минут или может выполняться задание через 5 минут и 10 секунд?

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

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

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

В зависимости от ответов на открытие вопросов в этом ответе вам, возможно, придется добавить еще более ошибку обработки ошибок. Если извлечение внешнего ресурса обычно довольно коротко, вы можете просто сохранить запись очереди, заблокированную select for update И когда задача завершена, обновите статус (или удалите запись, если хотите). Это заблокирует другие сервисные экземпляры от обработки записи, пока оно обрабатывается на другом сервере, и если сбой происходит во время обработки, транзакция должна быть возвращена назад, а другая услуга в кластере может забрать запись. (Хотя, вы можете увеличить тайм-аут транзакции до тех пор, пока вы думаете, что вам нужно.)

Если хранение блокировки базы данных долгое время не является жизнеспособным, вы можете изменить логику и добавить некоторые мониторинг на службы. Теперь, когда работа запускается обработка, его статус будет изменен с очередя для работы, а сервер, который обрабатывает запись, будет обновляться в записи. Может быть создан какой-то таблица состояния обслуживания, и каждый экземпляр обслуживания будет обновлять текущее время каждый раз, когда они опросы. Это позволило бы другим услугам в кластере переработать рабочие места, которые показывают как работает, но служба, которую они должны работать, не «проверяется» в течение определенного периода.

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

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

Балансировка сетевой нагрузки - это способ настроить пул компьютеров таким образом, чтобы они по очереди отвечали на запросы.Чаще всего это реализовано в серверных фермах:идентично настроенные машины, распределяющие нагрузку для веб-сайта или, возможно, фермы серверов терминалов.Вы также можете использовать его для фермы брандмауэров (ISA), точек доступа vpn, на самом деле, в любое время, когда у вас есть трафик TCP / IP, который стал слишком загруженным для одной машины, но вы все равно хотите, чтобы он отображался как отдельная машина для целей доступа.

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

Коммерческие балансировщики нагрузки существуют для обслуживания запросов в стиле HTTP, так что, возможно, на это стоит обратить внимание, но с функциями балансировки нагрузки W2k8 вам, возможно, лучше всего воспользоваться ими.

Для получения дополнительной информации о том, как настроить это в Win2k8, смотрите это Статья.

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

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

В противном случае вам может быть полезен поиск / публикация в ServerFault, поскольку код вашего приложения не (и не должен быть) строго осведомлен о том, что NLB вообще существует.

Редактировать:добавлена еще одна ссылка.

ПРАВКА (2-я):ОП исправил мой ошибочный вывод в "активном" противконцепция "пассивности".Мой ответ на это очень похож на мой первоначальный ответ, за исключением того, что "активная" служба (которая, поскольку вы используете WCF, легко может быть службой Windows) может быть разделена на две части:фактическая часть обработки и часть управления.Часть управления будет выполняться на одном сервере и действовать как циклический балансировщик нагрузки для других серверов, выполняющих фактическую обработку.Это немного сложнее, чем исходный сценарий, но я считаю, что это обеспечило бы значительную гибкость, а также обеспечило бы четкое разделение между вашей логикой обработки и управления.

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

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

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

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

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

Даже куратор Netflix имеет много рецептов, уже сделанных и использовать. Как и: Лидер выборов, распределенный замок и многое другое.

Я думаю, что у нас есть клиент Zookeeper для C #. Вы обязательно должны попробовать это варианты. # Опция3.

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