Какие шаблоны дизайна наиболее эффективны при создании приложений высокой доступности?

Кроме того, существуют шаблоны проектирования, которые следует избегать?

Ответы

Ответ 1

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

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

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

Давайте начнем с однопоточного сервера impl (самый простой - и концепции по-прежнему применяются к многопоточным, но у него есть свой собственный набор проблем0. Когда обрабатываемая команда нуждается в какой-то обработке транзакций.

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

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

Некоторые из этих проблем также присутствуют в системах мастер-работников.

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

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

Другой проблемой является представление конечных точек. то есть. клиент, подключенный к мастеру node, должен иметь возможность подключиться к новому хозяину, а затем слушать результаты? Или вы просто отмените все ожидающие результатов и позвольте клиентам повторно отправить? Если вы разрешаете обрабатывать ожидающие запросы запросы, нужен хороший способ определить конечные точки (клиенты) (т.е. Какой-то идентификатор клиента в поиске).

Также необходимо очистить код и т.д. (т.е. не хотите, чтобы данные ожидали, когда клиент будет снова подключаться, чтобы ждать всегда).

Используется много очереди. Поэтому многие люди используют некоторую шину сообщений (jms say для java), чтобы перетаскивать события транзакционным способом.

Terracotta (снова для java) решает много этого для вас - просто обновите память - терракота - ваш фасад/медиатор здесь. Они просто вставляют аспекты для вашего.

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

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

Сообщения служат (например, jms), которые часто используются для введения развязки между различными службами. С приличным сервером сообщений вы можете выполнять много маршрутизации сообщений (опять же, верблюд-верблюд или аналогичный, делает отличную работу). скажем, липкий потребитель против группы производителей jms и т.д., что также может обеспечить хороший переход на другой ресурс. JMS queue и т.д. Могут обеспечить простой способ распространения cmds в кластере, не относящийся к master/slave. (опять же, это зависит от того, выполняете ли вы LOB или пишете сервер/продукт с нуля).

(если я получу время позже, я буду убирать, возможно, поместить более подробную информацию в исправление грамматики орфографии и т.д.)

Ответ 2

Одним из подходов к созданию надежного программного обеспечения является программное обеспечение с ошибкой:

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

Ответ 3

Я бы рекомендовал прочитать Отпустите его! от Michael Nygard. Он излагает ряд анти-шаблонов, которые влияют на производственные системы, и шаблоны, которые помогают предотвратить переход одного из странствующих компонентов из всей системы. Книга охватывает три основные области; Стабильность, емкость и общий дизайн (охватывающие сети, безопасность, доступность и администрирование).

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

Ответ 4

Неправильно:

... и будет сервер хранения

Хорошо:

... и будет ферма (многократного) хранилища серверов с (несколькими) балансировщиками нагрузки спереди из них

  • Поставьте балансировщики нагрузки перед всем. На данный момент у вас может быть 4 backend, но в будущем у вас может быть 400 из них, поэтому разумно управлять ими только на LB, а не на всех приложениях, которые используют бэкэнд.

  • Используйте несколько уровней кеша.

  • Ищите популярные решения по ускорению (например, memcached).

  • Если вы собираетесь обновить систему, сделайте ее по частям несколькими шагами. Если вы сделаете это одним большим шагом (выключите старый, включите новый и помолите, он будет работать), скорее всего, он потерпит неудачу.

  • Используйте имена DNS для файлов, т.е. storage-lb.servicename разрешает адреса всех балансировщиков нагрузки. Если вы хотите добавить его, просто измените dns, все службы начнут использовать его автоматически.

  • Держите его просто. Чем больше систем вы будете зависеть, тем больше пострадает от вашего обслуживания.

Ответ 5

Разработка систем высокой доступности (HA) является активной областью исследований и разработок. Если вы посмотрите на ACM или IEEE, есть тонна исследовательских работ по качеству обслуживания (доступность, надежность, масштабируемость и т.д.) И как их достичь (свободная связь, адаптация и т.д.). Если вы ищете больше практических приложений, взгляните на отказоустойчивые системы и промежуточное программное обеспечение, которое создано для обеспечения возможности кластеризации, сетки или облака.

Репликация и балансировка нагрузки (a.k.a. обратный прокси) являются одними из наиболее распространенных моделей достижения HA-систем и часто могут выполняться без внесения изменений кода в базовое программное обеспечение, предполагая, что он не слишком тесно связан. Даже многие недавние предложения облаков достигаются в основном за счет репликации и балансировки нагрузки, хотя они имеют тенденцию создавать эластичность для решения широкого спектра требований к системе.

Создание компонентов программного обеспечения без учета состояния облегчает бремя репликации, поскольку само государство не нуждается в репликации вместе с программными компонентами. Безгражданство является одной из основных причин, по которым HTTP так хорошо масштабируется, но часто требуется, чтобы приложения добавляли их собственное состояние (например, сеансы), которые затем должны быть реплицированы.

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

Ответ 6

Как я понимаю, вы ищете конкретные шаблоны для использования в java-приложениях части архитектуры HA. Конечно, существует множество моделей и лучших практик, которые можно использовать, но на самом деле это не "шаблоны HA". Скорее, это хорошие идеи, которые можно использовать в контексте manys.

Я предполагаю, что я пытаюсь сказать следующее: Архитектура с высокой доступностью состоит из множества мелких деталей. Если мы выберем одну из этих мелких частей и рассмотрим их, мы, вероятно, обнаружим, что нет магических атрибутов HA для этого небольшого компонента. Если мы рассмотрим все остальные компоненты, мы найдем то же самое. Это когда они объединены в разумной манере, превратитесь в приложение HA.

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

Несмотря на все это, существуют шаблоны, которые особенно полезны в контексте HA. Многие из них описаны в классической книге "Шаблоны архитектуры корпоративных приложений" от Мартина Фаулера.

Ответ 7

Я интерпретирую " Высокая доступность" как " Время нулевого времени", которое может быть реализовано в соответствии с другим вопросом SE:

Внедрение Zero downtime для приложений Java

  • Переключатель A/B: (Обновление прокатки + Механизм возврата)
  • Параллельное развертывание - Apache Tomcat: (только для веб-приложений)
  • Задержка привязки порта
  • Расширенная привязка портов

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

Шаблоны для использования:

Proxy/Factory:

Попросите прокси-объект и прокси-сервер решить, где перенаправить запросы. Предположим, что у вас есть версия 1 и версия 2 программного обеспечения. Если клиенты подключаются со старым протоколом, перенаправляйте их на программное обеспечение Версии 1. Новые клиенты могут напрямую подключаться к версии 2. Прокси может иметь либо метод Factory, либо AbstractFactory для рендеринга новой версии программного обеспечения.

Strategy

Вы можете изменить алгоритм во время выполнения, выбрав один алгоритм из семейства алгоритмов. Если вы берете пример авиакомпаний, вы можете переключаться между алгоритмами DiscountFare и NormalFare во время месяцев непикового и пикового трафика.

Decorator:

Вы можете изменить поведение объекта во время выполнения. Добавьте новый класс и возложите дополнительную ответственность.

Adapter:

Полезно при изменении интерфейса или контракта между версией 1 и версией 2. Адаптер будет соответствующим образом отвечать как старым, так и новым клиентским запросам.

Общие рекомендации:

  • Свободная связь между объектами
  • Следуйте Принципы S.O.L.I.D в вашем приложении.

Обратитесь к sourcemaking статьи веб-сайта для вышеуказанных шаблонов для лучшего понимания.

Что не использовать:

Помимо шаблонов проектирования, вы должны принять некоторые меры предосторожности для достижения нулевого времени простоя для вашего приложения.

  • Не вводите единую точку сбоев в вашей системе.
  • Использование распределенных кешей (например, Terracotta)/блокировки экономно.
  • Удалите жесткую связь между службами. Удалите плотную связь между службами, используя шину обмена сообщениями/фреймворки (JMS, ActiveMQ и т.д.).

Ответ 8

Высокая доступность - это больше о доступности и избыточности оборудования, чем о соглашениях о кодировании. Есть несколько шаблонов, которые я использовал бы почти в каждом случае HA: я бы выбрал singleton pattern для моего объекта базы данных и использовал шаблон factory, чтобы создать синглтон, После этого factory может иметь логику для решения проблем доступности с базой данных (в которой происходит большинство проблем с доступностью). Например, если мастер недоступен, подключитесь к второму Мастеру для чтения и записи до тех пор, пока Мастер не вернется. Я не знаю, являются ли эти шаблоны наиболее заемными, но они наиболее эффективны в моем коде.

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

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