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

Шрифт
Интервал

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

одного высокоуровневого приложения.

5> Реплицированные сервисы с распределением

нагрузки

Реплицированный сервис с распределением нагрузки — простей-ший распределенный паттерн, известный многим. В рамках такого  сервиса все серверы идентичны друг другу и поддерживают входя-щий трафик. Паттерн состоит из масштабируемого набора серве-ров, находящихся за балансировщиком нагрузки. Балансировщик  обычно распределяет нагрузку либо по карусельному (round-robin)  принципу,  либо  с  применением  некоторой  разновидности  закре-пления  сессий.  В  данной  главе  приводится  конкретный  пример  развертывания такого сервиса с помощью Kubernetes. Сервисы без внутреннего состояния Сервисы без внутреннего состояния (stateless-сервисы) не требуют  для своей работы сохранения состояния. В простейших приложе-Глава 5. Реплицированные сервисы с распределением нагрузки 83 ниях, не хранящих состояние (stateless-приложениях), отдельные  запросы  могут  быть  направлены  разным  экземплярам  сервиса.  Примеры stateless-сервисов включают как сервисы доставки ста-тического контента, так и сложные промежуточные системы, при-нимающие и агрегирующие запросы от серверных сервисов.

Рис. 5.1. Простой реплицированный stateless-сервис

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

виса с  уровнем доступности «три девятки»  (99,9 %). У сервиса  с уровнем доступности 99,9 % в день есть 1,4 минуты на простой  (24  ×  60  ×  0,001). Даже исходя из того, что ваш сервис никогда не  отказывает, у вас есть не более 1,4 минуты на обновление про-граммного обеспечения, чтобы соблюсти уровень обслуживания  при использовании одного экземпляра сервиса. И это с учетом,  что  вы  обновляете  программное  обеспечение  раз  в  день.  Если  ваша  команда  серьезно  вступила  на  путь  Continuous  Delivery  и  вы  выпускаете  новую  версию  приложения  каждый  час,  то  84 Часть II. Паттерны проектирования обслуживающих систем у вас есть не более  3,6 секунды  на развертывание очередной вер-сии, чтобы соблюсти уровень обслуживания 99,9 % при исполь-зовании одного экземпляра сервиса. Стоит чуть задержаться —  и вы уже не вписываетесь в заявленные 0,1 % времени простоя. Можно,  конечно,  вместо  этого  всего  добавить  вторую  копию  сервиса  и  балансировщик  нагрузки.  Таким  образом,  пока  вы  развертываете  новую  версию  или  восстанавливаете  один  эк-земпляр сервиса после сбоя (что, надеюсь, происходит нечасто),  ваших ничего не подозревающих пользователей будет обслужи-вать второй его экземпляр.

По мере роста сервиса ему требуются дополнительные экземпля-ры  для  поддержки  большего  количества  одновременно  подклю-ченных пользователей.  Горизонтально масштабируемые  системы  поддерживают растущее количество пользователей путем добав-ления дополнительных копий сервиса (рис. 5.2). Это происходит  благодаря  использованию  паттерна  Load-balanced  Replicated  Serving (обслуживание с репликацией и балансировкой нагрузки).

Рис. 5.2. Горизонтальное масштабирование реплицированного stateless-приложения

Датчики готовности для балансировщика нагрузки

Репликация  и  балансировка  нагрузки,  конечно  же,  лишь  часть  паттерна реплицированного stateless-сервиса. При проектировании  Глава 5. Реплицированные сервисы с распределением нагрузки 85 реплицируемого сервиса  настолько  же  важно  разработать  и  раз-вернуть датчик готовности, к которому бы обращался балансиров-щик  нагрузки.  Мы  уже  рассматривали,  как  можно  использовать  датчики  работоспособности  в  оркестраторах  контейнеров,  чтобы  своевременно перезапускать приложения.  Датчик готовности  же  определяет, готово ли приложение обслужить запрос пользовате-ля. Необходимость такого различия обусловлена тем, что многие  приложения  требуют  некоторого  времени  на  инициализацию,  прежде  чем  они  смогут  обслуживать  пользовательские запро-сы.  Им,  возможно,  надо  подключиться  к  базе  данных,  загрузить  надстройки  либо  загрузить  файлы  из  сети.  Во  всех  этих  случаях  контейнеры  исправны , но  не готовы . При построении приложения,  использующего  паттерн  Replicated  Service,  не  забывайте  преду-смотреть специальный URL, реализующий проверку готовности. Практикум. Создание реплицированного сервиса с помощью Kubernetes В  следующем  примере  приводится  инструкция  по  разверты-ванию  реплицированного  stateless-сервиса  с  балансировщи-ком  нагрузки.  Эта  инструкция  подразумевает  использование  оркестратора  контейнеров  Kubernetes,  но  сам  паттерн  можно  реализовать и с помощью других оркестраторов. Для начала создадим простое NodeJS-приложение, которое вы-водит толкования слов из словаря.