Как сделать активные службы высоконадежными?

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

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

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

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

Действительно ли это - лучшее решение? Как люди обычно делают это?

По тому, как это-.NET C# приложение WCF, работающее на Windows Server 2008

8
задан Jader Dias 16 April 2010 в 20:45
поделиться

5 ответов

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

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

4
ответ дан 5 December 2019 в 21:17
поделиться

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

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

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

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

0
ответ дан 5 December 2019 в 21:17
поделиться

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

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

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

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

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

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

см. Здесь еще один подробный обзор установки и конфигурации NLB.

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

РЕДАКТИРОВАТЬ: добавлена ​​еще одна ссылка.

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

1
ответ дан 5 December 2019 в 21:17
поделиться

Есть некоторые требования, которые вы, вероятно, знаете, но у них есть не было описано в вопросе, который затрудняет дать осознанный ответ.Вот некоторые из этих вопросов:

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

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

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

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

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

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

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

1
ответ дан 5 December 2019 в 21:17
поделиться

Однажды я реализовал нечто подобное, используя ваше решение №3.

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

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

  1. Выполнять запрос типа « update resource_lock set resource_key = 1, где resource_key равен нулю ». (вы, конечно, также можете вставить идентификатор сервера, временную метку и т. д.)
  2. Если обновлено 0 строк: ничего не делать - другой экземпляр приложения уже извлекает ресурс.
  3. Если обновлена ​​1 строка: выберите ресурс и установите lock_key обратно в null .

У этого есть два преимущества:

  • Если один из ваших серверов выходит из строя, ресурс все равно будет извлекаться серверами, которые все еще работают.
  • Вы оставляете блокировку базе данных, это избавляет вас от необходимости реализовывать ее самостоятельно.
1
ответ дан 5 December 2019 в 21:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: