Создание микросервисов — страница 60 из 69

Разделение рабочих нагрузок

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

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

Распределение риска

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

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

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

AWS, к примеру, имеет региональную форму распределения, которую можно рассматривать как отдельные облака. Каждый регион, в свою очередь, разбит на две и более зоны доступности (AZ). Эти зоны в AWS являются эквивалентом дата-центра. Важно, чтобы сервисы были распределены по нескольким зонам доступности, поскольку инфраструктура AWS не дает гарантий доступности отдельно взятого узла или даже всей зоны доступности. Для своих вычислительных услуг эта инфраструктура предлагает только 99,95 % безотказной работы за заданный месячный период во всем регионе, поэтому внутри отдельно взятого региона рабочую нагрузку следует распределить по нескольким доступным зонам. Некоторых такие условия не устраивают, и вместо этого они запускают свои сервисы, также распределяя их по нескольким регионам.

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

Балансировка нагрузки

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

Рис. 11.4. Пример балансировки нагрузки с целью масштабирования количества экземпляров клиентского сервиса

Существуют балансировщики нагрузки всех форм и размеров, от больших и дорогих аппаратных приспособлений до балансировщиков на основе программных средств типа mod_proxy. У всех них общие основные возможности. Они распределяют поступающие к ним вызовы между несколькими экземплярами на основе определенного алгоритма, устраняя экземпляры, утратившие работоспособность, но не теряя при этом надежды на их возвращение при восстановлении нормального режима работы.

Некоторые балансировщики нагрузки предоставляют ряд полезных свойств. Одним из самых распространенных является возможность работы в качестве оконечного SSL-устройства, в котором входящие в балансировщик нагрузки HTTPS-соединения преобразуются в HTTP-соединения, в качестве которых они и попадают в сам экземпляр. Исторически издержки на управление SSL были довольно большими, и когда этот процесс берет на себя балансировщик нагрузки, он оказывает вам существенную услугу. В настоящее время это сильно упрощает настройки отдельных хостов, на которых запускаются экземпляры. Но, как говорилось в главе 9, смысл использования HTTPS заключается в обеспечении неуязвимости запросов от взлома злоумышленниками на маршруте их передачи, поэтому при использовании конечной точки SSL мы потенциально отчасти открываем свои данные. Снизить угрозу можно, поместив все экземпляры микросервисов в единую VLAN-сеть (рис. 11.5). VLAN является виртуальной локальной сетью, изолированной таким образом, что поступающие извне запросы могут пройти только через маршрутизатор, а в данном случае маршрутизатор является также балансировщиком нагрузки с возможностью выполнения роли конечной точки SSL. Единственная линия связи с микросервисами, идущая с внешней стороны VLAN-сети, использует протокол HTTPS, а внутри сети повсеместно применяется протокол HTTP.

Рис. 11.5. Использование конечной точки HTTPS в балансировщике нагрузки с VLAN-сетью с целью повышения безопасности

AWS предоставляет балансировщики нагрузок с конечными точками HTTPS в форме ELB-балансировщиков (Elastic Load Balancer — гибкий балансировщик нагрузки), позволяющие для реализации VLAN-сети воспользоваться его безопасными группами или виртуальными закрытыми облаками (VPC). Такую же роль в качестве программного балансировщика нагрузки может сыграть программа вроде mod_proxy. У многих организаций имеются аппаратные балансировщики нагрузки, автоматизация которых может быть затруднена. При таких обстоятельствах я встану на защиту программных балансировщиков нагрузки, установленных за аппаратными балансировщиками, что даст командам свободу их перенастройки в соответствии с их запросами. Надо считаться с тем фактом, что аппаратные балансировщики нагрузки нередко выходят из строя, становясь единой точкой отказа! Независимо от избранного вами подхода при рассмотрении вопроса о конфигурации балансировщика нагрузки относитесь к ней так же, как относились к конфигурации вашего сервиса: обеспечьте ее сохранение в системе управления версиями и возможность автоматического применения.

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

Системы на основе исполнителей

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