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

Следовательно, когда мы думаем о различных моделях развертывания, речь идет о хостах. Итак, сколько же у нас должно быть сервисов на хост?

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

Несколько сервисов на каждый хост

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

Рис. 6.6. Размещение на каждом хосте нескольких сервисов


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

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

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

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

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

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

Как говорит мой коллега Нил Форд (Neal Ford), многие наработанные нами приемы развертывания и управления хостом представляют собой попытку оптимизировать дефицит ресурсов. В прошлом при необходимости получения другого хоста у нас был единственный выбор: купить или арендовать другую физическую машину. Зачастую время выполнения заказа было весьма продолжительным, что приводило к возникновению долгосрочных финансовых обязательств. Поставка новых серверов лишь через каждые два-три года была для клиентов, с которыми мне приходилось работать, вполне обычным явлением, и получить дополнительные машины вне этого графика было очень трудно. Но компьютерные платформы, предоставляемые по требованию, резко снизили цены на вычислительные ресурсы, а развитие технологий виртуализации означало даже для внутренней инфраструктуры на основе использования хостов придание ей большей гибкости.

Приложения-контейнеры

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

Рис. 6.7. Размещение на каждом хосте нескольких сервисов


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

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

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

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

В конечном счете этот подход является еще одной попыткой оптимизировать дефицит ресурсов, которые могут просто больше не вмещаться. Если вы примете решение в качестве модели развертывания разместить несколько сервисов на одном хосте, я бы настоятельно рекомендовал присмотреться к независимо развертываемым микросервисам как к артефактам. Применяя. NET-технологию, этого можно добиться с помощью использования таких средств, как Nancy, а в Java эта модель поддерживается на протяжении многих лет. Например, имеющий довольно почтенный возраст встроенный контейнер Jetty создается для весьма облегченного автономного HTTP-сервера, составляющего ядро стека Dropwizard. Известно, что в Google в