Что такое микросервисы php

Что такое микросервисы: особенности архитектуры, примеры использования, инструменты

Что такое микросервисы: особенности архитектуры, примеры использования, инструменты

Архитектурный стиль микросервисов — это подход, при котором система строится как набор независимых и слабосвязанных сервисов, которые можно создавать, используя различные языки программирования и технологии хранения данных. Концепция микросервисов позволяет поддерживать слабую связанность сервисов в процессе работы над системой, что определяют паттерны Low Coupling и High Cohesion.

Подробности — в видео и текстовой расшифровке ниже.

Монолит vs микросервисы

При монолитной архитектуре система обычно состоит из 3 блоков: пользовательский интерфейс, хранилище данных и серверная часть. Серверная часть обрабатывает запросы, выполняет бизнес-логику, работает с БД, заполняет HTML-страницы. Любое изменение в системе приводит к обновлению версии серверной части приложения.

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

Что такое контракт

Контракт — это формализация возможностей взаимодействия с микросервисом. В случае с REST API эндпоинты сервиса и схема данных являются контрактом. Первоначальная разработка архитектуры — это декомпозиция системы на слабосвязанные сервисы, создание интерфейсов и связей между ними, поддержка целостности данных без потери производительности. Помочь с решением данной задачи могут шаблоны Tolerant Reader и Consumer-Driven Contracts.

Микросервисная команда

Команда не должна включать в себя больше людей, чем можно насытить двумя пиццами. Такое правило использовала компания Amazon при распиливания своего монолита в 2002 году. Вполне допустимо и правило developer per service, то есть один разработчик на один микросервис.

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

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

Микросервисный подход предполагает разбиение системы на сервисы по бизнес-требованиям. Сервисы включают в себя полный набор технологий: UI, storage, backend. Это приводит к созданию кросс-функциональных команд, имеющих достаточно компетенций для реализации всех необходимых сервисов, покрывающих 100% бизнес-функционала. Команды должны отвечать за все аспекты ПО, которое они разрабатывают, включая поддержку его в режиме 24/7. В таком случае возможность проснуться от звонка в 3 часа ночи — это очень сильный стимул писать хороший код.

Насколько большим должен быть микросервис

Логика работы сервиса должна полностью уместиться в голове одного разработчика, независимо от количества кода и людей. Проектируя систему, мы имеем выбор, как разработать каждый микросервис. Например:

Архитектура микросервиса даёт полную свободу в выборе технологий и инструменария.

Инструментарий для реализации микросервисов

В процессе реализации микросервисной архитектуры существенным упрощением будет использование систем CI/CD, системы оркестрации, Service Discovering, мониторинга и сбора логов.

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

Цепочка синхронных вызовов микросервисов приведет к ожиданию ответов от всех сервисов по очереди. Поэтому используйте правило «Один синхронный вызов на один запрос пользователя», как это сделали в The Guardian, либо полностью асинхронный API, как в Netflix. Один из способов сделать асинхронный API использовать систему обработки очередей, например, RabbitMQ, Apache Kafka или ActiveMQ.

Источник

Микросервисы для начинающих

Оглядываясь примерно на пять лет назад в прошлое, можно заметить, насколько сильно с тех пор изменилось отношение к архитектуре микросервисов. Поначалу они были чрезвычайно популярны. После успеха Netflix, Amazon и Gilt.com разработчики решили, что де-факто разработка микросервисов не отличается от разработки приложений. Теперь же все поняли, что микросервисы представляют из себя новый архитектурный стиль, который эффективен для решения определенных задач, имеет свои плюсы и минусы.

Чтобы понять, что такое микросервисы и в каких случаях их следует использовать, мы обратились к Джейме Буэльта (Jaime Buelta), автору книги «Hands-On Docker for Microservices with Python». Он рассказал о преимуществах этой архитектуры, а также поделился рекомендациями для разработчиков, планирующих перейти на нее с монолитов.

Преимущества и риски

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

Буэльта объясняет: «Микросервисная архитектура — это способ структурирования системы, при которой несколько независимых сервисов общаются друг с другом определенным образом (обычно это происходит с помощью web-сервисов RESTful). Ключевая особенность состоит в том, что каждый микросервис способен обновляться и развертываться независимо от остальных».
Архитектура микросервисов определяет не только то, как вы создаете свое приложение, но и то, как организована ваша команда.

«Одна независимая команда может полностью отвечать за микросервис. Это позволяет организациям расти, не сталкивая разработчиков друг с другом», — объясняет Буэльта.
Одно из основных преимуществ микросервисов заключается в том, что они позволяют внедрять нововведения без особого влияния на систему в целом. С помощью микросервисов вы можете выполнять горизонтальное масштабирование, иметь четкие границы модулей, использовать разнообразные технологии и вести параллельную разработку.

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

Переход от монолита к микросервисам

Мартин Фаулер, известный автор и консультант по программному обеспечению, советует придерживаться принципа «сначала — монолит». Это связано с тем, что использовать микросервисную архитектуру с самого начала разработки рискованно, поскольку в большинстве случаев она подходит только для сложных систем и больших команд разработчиков.
«Основной критерий, который должен побуждать вас к переходу на новую архитектуру — это численность вашей команды. Небольшим группам не стоит этого делать. В подобных условиях разработчики и так понимают все, что происходит с приложением, и всегда могут задать уточняющий вопрос коллеге. Монолит отлично работает в этих ситуациях, и поэтому практически каждая система начинается с него», — считает Джейме. Это подтверждает «правило двух пицц» Amazon, согласно которому команду, ответственную за один микросервис, можно прокормить двумя пиццами — иначе она слишком большая.

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

Рекомендации по переходу на микросервисы

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

Джейме советует переходить на архитектуру правильно, чтобы потом все не переделывать. «После завершения перехода изменить границы микросервисов будет тяжелее. Стоит уделить побольше времени на начальную фазу проекта», — добавляет он.
Переход с одного шаблона проектирования на другой — это серьезный шаг. Мы спросили, с какими проблемами Джейме и его команда сталкивались во время миграции на микросервисы, на что он ответил:

«На деле основные трудности связаны с людьми. Эти проблемы, как правило, недооценивают, но переход на микросервисы фактически меняет способ работы разработчиков. Задача не из легких!». Он добавляет: «Я лично сталкивался с подобными проблемами. Например, мне приходилось обучать и давать советы разработчикам. Особенно важно объяснять, почему необходимы те или иные изменения. Это помогает людям понять причины внедрения всех нововведений, которые могут прийтись им не по душе.

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

Причины выбора Docker, Kubernetes и Python в качестве технологического стека

Мы спросили Буэльту, какие технологии он предпочитает для внедрения микросервисов. Касательно выбора языка ответ оказался прост: «Python для меня — лучший вариант. Это мой любимый язык программирования. Этот язык хорошо подходит для микросервисов. Его удобно читать и легко применять. Кроме того, Python обладает широким функционалом для веб-разработки и динамичной экосистемой сторонних модулей для любых потребностей. К этим потребностям относится подключение к другим системам, например, к базам данных, внешним API и т.д.».

Docker часто рекламируется как один из самых важных инструментов для микросервисов. Буэльта объяснил, почему:

«Docker позволяет инкапсулировать и копировать приложение в удобных стандартизированных пакетах. Это уменьшает неопределенность и сложность среды. Также это значительно упрощает переход от разработки к производству приложений. Вдобавок ко всему, уменьшается время использования оборудования. Вы можете разместить несколько контейнеров в разных средах (даже в разных операционных системах) в одной физической коробке или виртуальной машине».

«Kubernetes позволяет развертывать несколько контейнеров Docker, работающих скоординированным образом. Это заставляет разработчиков мыслить кластеризованно, помня о производственной среде. Также это позволяет определять кластер с помощью кода, чтобы новые развертывания или изменения конфигурации определялись в файлах. Все это делает возможными методы наподобие GitOps (о них я писал в своей книге), при этом сохраняя полную конфигурацию в системе управления версиями. Каждое изменение вносится определенным и обратимым образом, поскольку оно представляет из себя регулярное git-слияние. Благодаря этому можно очень легко восстанавливать или дублировать инфраструктуру».

«Придется потратить время, чтобы обучиться Docker и Kubernetes, но это того стоит. Оба инструмента очень мощные. К тому же, они поощряют вас работать таким образом, чтобы избежать проблем при производстве», — считает Буэльта.

Многоязычные микросервисы

При разработке микросервисов можно использовать разнообразные технологии, поскольку за каждый из них в идеале отвечает независимая команда. Буэльта поделился своим мнением о многоязычных микросервисах: «Многоязычные микросервисы — это здорово! Это одно из основных преимуществ архитектуры. Типичный пример многоязычного микросервиса — перенос устаревшего кода, написанного на одном языке, на новый. Микросервис может заменить собой любой другой, который предоставляет тот же внешний интерфейс. При этом его код будет совершенно иным. К примеру, я переходил со старых приложений PHP, заменяя их аналогами, написанными на Python». Джейме добавил: «Работа с двумя или более платформами одновременно поможет лучше разобраться в них и понимать, в каких случаях их лучше использовать».

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

Об авторе

Джейме Буэльта (Jaime Buelta) — профессиональный программист и Python-разработчик, который за свою многолетнюю карьеру познакомился со множеством различных технологий. Он разрабатывал программное обеспечение для различных областей и отраслей, включая аэрокосмическую, сетевую и коммуникационную, а также промышленные системы SCADA, онлайн-сервисы для видеоигр и финансовые сервисы.

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

Источник

Готовим простой блог на микросервисах, пишем свой микрофреймворк на php и запускаем все на Docker с примерами

А что если я скажу вам, что новый продукт можно сразу начинать писать на микросервисной архитектуре, а не заниматься распилом монолита? Это вообще нормально? Удобно? Хотите узнать ответ?

Задача: необходимо написать за выходные (время ограниченно 10-15 часами) сферический блог на микросервисах, на php, не используя никаких фреймворков. Можно пользоваться здравым смыслом. А еще забудем о том что такое фронтенд и вспомним что мы жить не можем без виртуализации. Выберем Docker. Интересно? Вперед под кат.

f7fb566a3f724874bf53cdb8e3b37d7a

Микросервисы

Если вам интересен микросервисный подход, но вы не знаете с чего начать, начните с книги «Building Microservices» Сэма Ньюмена. Постараюсь немного описать основные моменты данного подхода, если у вас будут какие-то дополнения, пишите пожалуйста в комментариях. И вообще по любому поводу пишите, я не претендую на истинность какого-либо из описанных ниже подходов, особенно в Вашем конкретном случае.

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

Суть микросервисов легко понять в сравнении с монолитной архитектурой. Как у нас выглядит обычный движок для блога? Грубо говоря это просто одно приложение. Работа с статьями, комментариями, страницами, пользователями и прочими функциональными единицами заключена в едином пакете исходного кода, который не делится никак.

image loader

Где все связи между компонентами — это вызовы внутри кода, какие-то отношения между классами, паттерны и т.п. или даже просто говнокод, если нельзя отделить одно от другого.

Как будет выглядеть наш блог? Да примерно также, если честно.

image loader

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

Зачем это нужно? Сразу определимся, что наверное, это нужно не всем. Это должно быть очень удобно, если вы — достаточно крупная компания, способная выделить по команде разработки на каждый сервис. Думаю, даже средним компаниям, если выделить по человеку на каждый сервис будет тоже неплохо. Впрочем, даже если ты один на всю компанию, ты сможешь найти в микросервисах что-то интересное.

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

Итак, позитивные вещи, которые я смог выделить для себя, в целом все они проходят под одним трендом: Невероятное удобство для разработки:

Что должно уметь наше приложение? Так то не очень много.
Четыре страницы:

Docker

image loader

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

Кстати, вот ссылка на репу, из которой вы можете скачать и запустить блог, посмотреть что-то по коду ниже. https://github.com/gregory-vc/blog

Сколько будет контейнеров в нашем простейшем блоге? Контейнер, это кстати по сути виртуализация отдельного сервера, который общается по сети с другими контейнерами, правда если проводить жесткую аналогию контейнер=сервер, от некоторых контейнеров нужно будет отказаться, но тем не менее. Для простейшей реализации блога на микросервисах я насчитал 24 контейнера. Давайте посмотрим.

Зачем на по две копии некоторых сервисов? Потому что с одной будет не интересно и не понятно.

Файл docker-compose, который развернет все это одной командой выглядит вот так:
https://github.com/gregory-vc/blog/blob/master/host/docker-compose.yml
Из самого интересного рассмотрим настройки php контейнера нашего шлюза.

Раздел описания контейнера links, это по сути просто редактирование /etc/hosts/

Где по обозначенному хосту мы просто имеем доступ к другому контейнеру через внутреннюю сеть докера.

А раздел environment — это просто обозначение переменных, которые мы сможем достать с вами внутри приложения через getenv(). Сделано так, чтобы файл docker-compose был единой точкой входа для настройки всего приложения.

В то время как структура наших сервисов выглядит как просто директории лежащие рядом,

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

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

Сервис Gate

image loader

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

Итак, у нас есть php и больше ничего. Хотя, давайте возьмем хотя бы composer, куда без него. Создадим еще две директории, одну с нашим микрофреймворком, который мы сейчас напишем, вторую для public скриптов, js, и прочих ресурсов.

В composer просто укажем, откуда осуществлять autoload, чтобы нам самим с этим не заморачиваться, и подключим сгенеренный autoload в public/index.php

Так, что-то у нас уже есть, давайте определимся что нам вообще еще будет надо?

Напишем вот такое хранилище объектов, чтобы не создавать их где попало, а иметь возможность получить доступ (inject) к уже созданным в любой точке приложения со всем нужными зависимостями (dependency). Мы не будем развлекаться с Reflection и прочими интересными штуками, время у нас жестко ограничено.

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

В приложении получаем request, маппим в роутере существующий экшен существующего контроллера по этому реквесту, одновременно еще записываем в request все пост или гет переменные, что нам пришли.

Выполняем метод контроллера, получаем response, рендерим response и показываем результат нашей работы, все.

Каркас есть, теперь нам надо работать с сервисами, создаем директорию с сервисами, создаем класс каждого сервиса, описываем точки доступа к каждому из сервисов. Наследуем их от основного класса сервисов, где реализуем варианты запросов.

Там внутри при запросе выбираем рандомны коннектор из предоставляемых сервисом, как-то так

Делаем запрос, из контроллера и рендерим, вот так:

Нам нужно отрендерить, но как? Шаблонизаторов у нас нет. Писать свой? Ну нет. Просто используем php.

Черезвычайно мощный шаблонизатор размером с 4 строчки.

Сервис post и comment

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

Итак? Если честно, это почти все, что нам нужно, не считая авторизации.
Мы можем делать запросы gate на любой сервис, с любого другого сервиса на любой другой.

Сервис авторизации
Схема проста: мы имеем юзеров и их доступы на сервере авторизации, мы делаем из шлюза запрос на авторизацию, генерируем токен, возвращаем его шлюзу и еще юзера, кладем юзера и токен в сессию и все. Незабываем посылать токен вместе с запросом на добавление поста, потому что что? Правильно, сервис постов пойдет в сервис авторизации и спросит, а правда ли что этот токен хорош? В зависимости от результата генерим разные эксепшены.

Результат

Вообще, можете скачать и развернуть его одной командой, напомню репозиторий: https://github.com/gregory-vc/blog

Где подходило по смыслу — я вывел для наглядности какой именно нодой был сгенерен тот или иной блок.

Еще меня впечатлило время генерации странички. Это 5-9 мс для странички с постом и несколькими комментариями (!). Да, все это необъективно, да, все это попугаи, да, микросервисы тут не при чем, да, смотря с чем сравнивать. Но. Тот же ларавель генерит свою страничку, вообще без запросов и данных, просто приветствие, за 90 мс, на моей же машине. Это в 10-20 раз дольше.

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

А главное это невероятный потенциал для масштабирования этого блога под просто невероятные нагрузки. Никто не помешает например потом взять и переписать сервис комментариев на Go.

Проблемы

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

Источник

Моя дача
Adblock
detector