Чек-лист микросервисной архитектуры

Чем-то коллегам в отрасли приглянулся этот списочек, несколько раз просили перепостить. Это некий «снепшот» моего понимания микросервисного подхода трехлетней давности, сегодня я бы что-то в этом списке наверняка поменял, дополнил, или, наоборот, ослабил. А тогда (при проектировании Modeus) мне нужен был этот список как максимально полный перечень, чтобы быть уверенным, что мы ничего не упускаем. При этом понятно было, что какие-то из пунктов мы в моменте обеспечить не можем, или даже рано — масштаб еще не тот. Но было важно сделать этот временный отказ осознанным. Возможно, именно в такой роли этот список может быть полезен кому-то и сейчас — если отказываться от каких-то пунктов, то обоснованно и осознанно.


  1. Приложение состоит из нескольких четко идентифицированных сервисов, разрабатываемых отдельно, и работающих в разных процессах ОС.
  2. Все сервисы имеют ограниченный размер и сложность, позволяющие без слишком неприятных затрат и рисков любой одиночный сервис выкинуть и переписать заново, и удерживать сложность любого сервиса в одной средней голове.
  3. Сервисы построены вокруг тесно связанных моделей в ограниченном контексте (DDD bounded contexts), а иногда делятся дополнительно под давлением НФТ.
  4. Сервисы разворачиваются в контейнерах под управлением контейнерной системы оркестрации.
  5. Образ сервиса содержит все зависимости и не требует специальной (зависящей от сервиса) подготовки хоста.
  6. Сервисы взаимодействуют друг с другом через протоколы, не зависящие от технологии реализации сервисов.
  7. Сервисы могут быть написаны на нескольких различных технологических стеках.
  8. Сервисы могут иметь свою БД, но не имеют прямого доступа к БД других сервисов.
  9. Для взаимодействия сервисов активно используется асинхронный обмен сообщениями (messaging).
  10. Кроме системы оркестрации для работы с сервисами создана, поддерживается и развивается отдельной командой развитая (как внутренний продукт) инфраструктурная платформа микросервисов, обеспечивающая их разработку, развертывание (CI/CD), исполнение и управление (мониторинг, диагностика, и т. п.).
  11. Инфраструктурная платформа разрабатывается с применением практик Infrastructure as a Code.
  12. Создание нового сервиса и его интеграция с другими по синхронным/асинхронным каналам — дешевая автоматизированная в платформе операция (< 1 ч*ч), не требующая участия кого-либо, кроме прикладного программиста.
  13. Для всех сервисов на уровне платформы обеспечено обнаружение зависимостей, т.к что сервису нужно знать только логическое имя другого сервиса.
  14. Разрешением зависимостей можно управлять в runtime, отделяя части трафика по признакам на отдельные экземпляры (QoS), или пропуская через промежуточные прокси-сервисы.
  15. Для всех сервисов на уровне платформы обеспечено централизованное унифицированное журналирование, не требующее работы специалистов при добавлении нового сервиса.
  16. Для всех сервисов на уровне платформы обеспечено централизованное унифицированное конфигурирование, не требующее работы специалистов при добавлении нового сервиса.
  17. Для всех сервисов на уровне платформы обеспечен централизованный унифицированный мониторинг доступности и здоровья, не требующее работы специалистов при добавлении нового сервиса.
  18. Для всех сервисов на уровне платформы обеспечен централизованный унифицированный мониторинг, сбор и анализ технических и бизнес-метрик, включая производительность, не требующее работы специалистов при добавлении нового сервиса.
  19. Прикладной программист может самостоятельно, дешево и просто добавить атрибут в журнал, по которому будет возможен поиск и метрику, по которой возможно создание графиков и алертов.
  20. Обеспечена отладочная/диагностическая трассировка вызовов от входа через все синхронно вызываемые сервисы до БД включительно.
  21. Сервисы обновляются по отдельности или малыми группами.
  22. Работает по несколько экземпляров каждого сервиса, нагрузка перераспределяется между ними.
  23. Одновременно может работать несколько разных (близких) версий сервиса.
  24. Сервисы сами обновляют необходимые им структуры данных.
  25. Не используется никаких распределенных транзакций, вместо них — саги, eventual consistency, идемпотентные операции, протоколы отката и т. п. паттерны.
  26. Сервисы тестируются по отдельности.
  27. Обновления системы проходят с нулевым простоем.
  28. Сбой отдельного узла не оказывает значимого влияния на функционирование и доступность системы (практика chaos monkey).
  29. В случае сбоя сервис быстро останавливается (а не виснет) и система оркестрации его перезапускает.
  30. Для тестирования сервиса может быть собрана группа сервисов из одной (или нескольких одноименных) ветки-на-фичу (feature branch).
  31. Отдельные стенды для тестирования/демонстрации системы или фрагмента системы из нескольких сервисов создаются платформой быстро, дешево, и без участия специалистов.
  32. Перенос нужных версий БД с одного стенда на другой производится быстро, дешево, и без участия специалистов, местами — автоматически с зачисткой чувствительных данных.
  33. Обновления сервисов и инфраструктуры описано кодом и корректность этих кодов обновления автоматически тестируется на тестовых стендах (в delivery pipeline).
  34. Для сервисов проводятся автоматические тесты на соблюдение контракта платформы.
  35. Для сервисов автоматически строится фактическая диаграмма взаимодействия.
  36. Для всех сервисов есть гарантированно точные описания интерфейсов (REST, Events) и контрактов (JSON schema, etc), обновляемые не вручную отдельно, а как неизбежная часть цикла разработки.
  37. Для каждого поддерживаемого технологического стека заготовлен проект-стартер, позволяющий создать болванку корректно работающего сервиса, не делающего ничего, за 5 минут.
  38. Новая команда может подключиться к разработке нового сервиса за один день, прогнать через тесты и выпустить его на PROD.
  39. Canary releases. Для новых версий сервисов разворачивается небольшое число экземпляров, автоматически контролируется успешность вызовов к ним и при наличии большого числа ошибок или выходов за SLA версия откатывается и автоматически ставится дефект.
  40. Для сервисов определены и контролируются автоматически контракты НФТ — производительность (задержка, пропускная способность), ресурсоемкость.
  41. Сервисы активно используют паттерны для обработки отказов смежных сервисов — fallback, повторы вызовов, таймауты, и т. п.
  42. Сервисы толерантны к незначительным изменениям форматов своих зависимостей (добавление атрибутов и т. п.).
  43. Все сервисы могут работать в тестовом режиме, когда отдельные зависимости не требуются и заменяются встроенными заглушками c тестовыми данными.
  44. На уровне платформы есть механизмы контроля содержимого всех входящих/исходящих запросов и сообщений для любого сервиса.
  45. Количество экземпляров сервиса может автоматически меняться в зависимости от нагрузки.
  46. Количество хостов кластера системы оркестрации может автоматически меняться в зависимости от нагрузки.
  47. Для отдельных экземпляров или для сервиса в целом можно во время выполнения менять конфигурационные параметры (например, менять детализацию журналирования) и выдавать команды обслуживания (например, сбрасывать кеши).
  48. Платформа предоставляет готовые библиотеки/средства для решения типичных задач взаимодействия сервисов (транзакции-саги, передача реплик данных, автоматическое создание очередей, и т. п.).
  49. В любой момент времени у каждого сервиса есть одна небольшая команда-владелец, отвечающая за него включая PROD (хотя могут быть изменения и от других команд и выделенная служба эксплуатации 1-2 линии).
  50. Клиентские приложения также модульны (micro frontends) и на них распространяется большинство вышеперечисленных принципов и требований.

 

Copyright © 2023 Igor Bespalchuk