Распределенные системы. Паттерны проектирования - страница 10

стр.

ных библиотек, их реализующих.

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

Резюме

Распределенные  системы  необходимы  для  того,  чтобы  обе-спечить  уровень  надежности, гибкости  и  масштабируемости,  ожидаемый от современных компьютерных программ.  Проектирование распределенных систем пока остается «чер-ной  магией»  для  посвященных,  а  не  наукой,  доступной  не-профессионалу.  Выявление  общих  шаблонов  и  практик  упо-рядочило и усовершенствовало подходы к алгоритмическому  и объектно-ориентированному программированию. Эта книга  призвана сделать то же для распределенных систем. Поехали! Часть I

Одноузловые паттерны проектирования

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

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

Мотивация

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

цессорных  ядра  и  8  Гбайт  оперативной  памяти).  Такой  лимит  может  также  привести  к  разделению сфер  ответственности  команд разработчиков (например, конкретная команда отвеча-ет за определенный образ). Наконец, это может способствовать  разделению  обязанностей  между  частями  кода  (конкретный  образ отвечает за конкретную функциональность). Все  эти  причины  побуждают  делить  приложение  на  группу  контейнеров даже в пределах одной машины. Сначала рассмо-Часть I. Одноузловые паттерны проектирования 31

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

Исходя  из  всех  этих  причин,  необходимо  поместить  сервис,  который  непосредственно  взаимодействует  с  пользователем,  и фоновый загрузчик в отдельные контейнеры. Так можно бу-дет закрепить за ними разный объем памяти и вычислительных  ресурсов,  что,  к  примеру,  позволит  фоновому  загрузчику  по  возможности  «забирать»  процессорное  время  у  пользователь-ского  сервиса  в  те  периоды,  когда  он  слабо  нагружен.  Кроме  того,  раздельное  назначение  вычислительных ресурсов  двум  контейнерам  позволит  сделать  так,  чтобы  фоновый  загрузчик  завершался  раньше  пользовательского  сервиса  в  случае  их  конфликта  за  ресурсы,  вызванного  утечкой  или  избыточным  распределением памяти.