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

Наши сервисы выставляют напоказ программный интерфейс приложения — Application Programming Interface (API), и работающие на нас сервисы связываются с нами через эти API. Нужно также подумать о технологии, позволяющей не привязывать сами интерфейсы к потребителям. Это может означать выбор API, нейтральных по отношению к тем или иным технологиям, чтобы гарантировать отсутствие ограничений в выборе технологий. На страницах этой книги мы еще не раз вернемся к вопросу о важности качественных, ни к чему не привязанных API.

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

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

Основные преимущества

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

Технологическая разнородность

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

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

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

Рис. 1.1. Микросервисы позволяют упростить использование разнообразных технологий

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

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

Устойчивость

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

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

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

Масштабирование

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

Рис. 1.2. Можно расширять только те микросервисы, которые в этом нуждаются

Именно по этой причине микросервисами воспользовалась компания Gilt, занимающаяся продажей через Интернет модной одежды. Начав в 2007 году с использования монолитного Rails-приложения, к 2009 году компания столкнулась с тем, что используемая система не в состоянии справиться с возлагаемой на нее нагрузкой. Разделив основные части своей системы, Gilt смогла намного успешнее справляться со всплесками трафика, и теперь компания использует 450 микросервисов, каждый из которых запущен на нескольких отдельных машинах.

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

Простота развертывания

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

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

За последние пару лет технология в данной области сильно изменилась, и тема развертывания в мире микросервисов более глубоко будет рассмотрена в главе 6.

Решение организационных вопросов

У многих из нас имеется опыт решения проблем, связанных с большими командами разработчиков и объемными базами исходного кода. Если команда разбросана по разным местам, проблема может только усугубиться. Также общеизвестно, что небольшие команды, работающие с небольшим объемом исходного кода, как правило, показывают более высокую продуктивность.

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

Компонуемость