digital-garden/notes/Микросервисы. Паттерны разработки и рефакторинга.md
2024-06-13 21:01:37 +03:00

101 lines
13 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
author: "[[Ричардсон Крис]]"
---
Обобщенное определение микросервисной архитектуры (или микросервисов) звучит так: это стиль проектирования, который разбивает приложение на отдельные сервисы с разными функциями. Заметьте, что размер здесь вообще не упоминается. Главное, чтобы каждый сервис имел четкий перечень связанных между собой обя­занностей.
В микросервисной архитектуре единицей модульности является сервис. Серви­сы обладают API, которые служат непроницаемым барьером. В отличие от пакетов в Java API нельзя обойти, чтобы обратиться к внутреннему классу.
Одна из проблем термина "микросервис" то, что в глаза сразу бросается "микро". Это подразумевает, что сервис должен быть очень маленьким. В реальности размер не является полезной характеристикой.
Определение хорошо спроектированного сервиса лучше связать с возможностью разрабатывать его в небольшой команде, как можно быстрее и минимально взаимо­ действуя с другими командами.
## Достоинства микросервисной архитектуры
- Непрерывная доставка и развертывание сложных приложений за счет слабой связности сервисов. Сервисы взаимодействуют только через API. Также необходимы автоматические тесты.
- Сервисы небольшие и простые в обсуживании
- Независимосе горизонтальное масштабирование.
- Лучшая изоляция неполадок. Если один сервис выйдет из строя, все остальные продолжат работать.
- Для каждого сервиса возможно использовать свой язык программирования, который подходит для решения конкретной задачи.
- Можно также использовать различные версии фреймворков в разных сервисах, тем самым постепенно обновляя версии зависимостей у сервисов.
- Болee эффективное утилизирование ресурсов. Некоторые сервисы требуют больше ЦПУ, некоторые больше ОЗУ.
## Недостатки микросервисов
- Выше порог входа в разработку.
- Сложно определить границы сервисов.
- Развертывание функций, которые охватывают несколько сервисов, требуют тщательной координации.
- Легче разарабатывать каждый отдельный сервис, но сложнее разрабатывать всю систему целиком. Сложнее выстраивать межсервисное взаимодействие.
### Сложно определить границы сервисов
Если вы неправильно разделили систему, у вас полу­ чится распределенный монолит — набор связанных между собой сервисов, которые необходимо развертывать вместе.
Распределенному монолиту присущи недостатки как монолитной, так и микросервисной архитектуры.
### Сложность распределенных систем
Ваш код должен уметь справляться с частичными сбоями и быть готовым к недоступности или высокой латентности удаленного сервиса.
Каждый сервис имеет собственную базу данных, что затруд­ няет реализацию комбинированных транзакций и запросов.
### Развертывание функций, которые охватывают несколько сервисов
Вам необходимо выработать план «выкаты­ вания» обновлений, который запрашивает развертывание сервисов с учетом их за­ висимостей.
## Каждому сервису своя БД
На этапе выполнения сервисы изолированы друг от друга — ни одному из них, например, не придется ждать из-за того, что другой сервис заблокировал БД.
> Это не значит, что нужно выделять целый сервер БД.
К сожалению, такой подход чреват некоторыми существенными проблемами. Традиционная методика с использованием распределенных транзакций (2PC) не подходит для современных приложений. Вместо этого согласованность данных следует обеспечивать с помощью шаблона «Повествование».
## Общие библиотеки
У вас также может возникнуть желание задействовать разделяемые библиотеки в микросервисной архитектуре. Но нужно убедиться, что это не приведет к связыванию ваших сервисов.
Старайтесь применять библиотеки для функций, изменение которых маловероятно.
## Механизмы обнаружения сервисов
Сетевое местоположение назначается экземплярам сервисов динамически. Более того, набор этих экземпляров постоянно меняется из-за автоматического масшта­ бирования, отказов и обновлений. Из-за этого ваш клиент должен использовать обнаружение сервисов.
### Обнаружение на уровне приложения
![](d002f312-ae64-4767-a71c-9abf81cddfe3.png)
Одно из преимуществ обнаружения сервисов на уровне приложения — то, что в нем предусмотрена возможность развертывания сервисов на разных платформах.
Один из недостатков этого подхода связан с тем, что он требует наличия библио­ теки обнаружения сервисов для каждого языка, а возможно, и фреймворка, который вы применяете.
Еще одной от­ рицательной стороной обнаружения сервисов на уровне приложения является то, что настройка и обслуживание реестра ложатся на вас.
### Обнаружение сервисов с помощью платформы
Многие современные платформы развертывания, такие как Docker и Kubernetes, имеют встроенные реестр и механизм обнаружения сер­ висов.
Платформа развертывания выдает каждому сервису DNS-имя, виртуальный IP-адрес (VIP) и привязанное к нему доменное имя. Клиент делает запрос к DNS- имени/VIP, а платформа развертывания автоматически направляет его к одному из доступных экземпляров сервиса.
В итоге регистрация и обнаружение сервисов, а также маршрутизация запросов выполняются самой платформой.
![](0346f52a-8279-45a0-83e7-065a9969ffe0.png)
Один из недостатков метода связан с тем, что он поддерживает обнаружение только тех сервисов, которые были развернуты на данной платформе. Например, как отмечалось при описании обнаружения на уровне приложения, платформа Kubernetes может обнаружить только те сервисы, которые на ней запущены.
Несмо­тря на это ограничение, рекомендую использовать обнаружение сервисов на уровне платформы везде, где это возможно.
## Обмен сообщениями без брокера
Отсутствие брокера дает несколько преимуществ.
- Более легковесный сетевой трафик и меньшие задержки, поскольку сообщения передаются напрямую от отправителя к получателю и не должны проходить через брокер.
- Брокер сообщений не станет узким местом или единой точкой отказа.
- Более простое администрирование, так как вам не нужно настраивать и обслу­ живать брокер сообщений.
Но какими бы заманчивыми ни были эти преимущества, отсутствие брокера со­ общений чревато существенными недостатками.
- Сервисы должны знать о местонахождении друг друга и, следовательно, исполь­зовать один из механизмов обнаружения.
- Снижена степень доступности, поскольку отправитель и получатель должны оставаться доступными на время передачи сообщения.
- Возникают дополнительные трудности с реализацией таких механизмов, как гарантированная доставка.
Пониженная доступность и потребность в обнаружении сервисов совпадают с недостатками, присущими синхронным запросам/ответам.
Из-за этих ограничений в большинстве промышленных приложений использу­ ется архитектура с брокером.
## Saga или Повествование
Повествование — это последовательность локальных транзакций, которые координируются путем обмена сообщениями. Повествования сложнее традиционных ACID-транзакций, но они хорошо подходят для многих ситуаций.
У них есть одно ограничение — отложенная согласованность (eventual consistency). Если вам нужно, чтобы данные обновлялись автоматически, они должны находиться в пределах одного сервиса, что может помешать декомпозиции.
## Прочие советы
Агрегация журналов. Записывайте поведение сервисов и сохраняйте эти записи на центральном сервере с поддержкой поиска и оповещений.
Распределенная трассировка. Назначайте каждому внешнему запросу уникаль­ ный идентификатор и отслеживайте его перемещение между сервисами.