Чем-то коллегам в отрасли приглянулся этот списочек, несколько раз просили перепостить. Это некий «снепшот» моего понимания микросервисного подхода трехлетней давности, сегодня я бы что-то в этом списке наверняка поменял, дополнил, или, наоборот, ослабил. А тогда (при проектировании Modeus) мне нужен был этот список как максимально полный перечень, чтобы быть уверенным, что мы ничего не упускаем. При этом понятно было, что какие-то из пунктов мы в моменте обеспечить не можем, или даже рано — масштаб еще не тот. Но было важно сделать этот временный отказ осознанным. Возможно, именно в такой роли этот список может быть полезен кому-то и сейчас — если отказываться от каких-то пунктов, то обоснованно и осознанно.
- Приложение состоит из нескольких четко идентифицированных сервисов, разрабатываемых отдельно, и работающих в разных процессах ОС.
- Все сервисы имеют ограниченный размер и сложность, позволяющие без слишком неприятных затрат и рисков любой одиночный сервис выкинуть и переписать заново, и удерживать сложность любого сервиса в одной средней голове.
- Сервисы построены вокруг тесно связанных моделей в ограниченном контексте (DDD bounded contexts), а иногда делятся дополнительно под давлением НФТ.
- Сервисы разворачиваются в контейнерах под управлением контейнерной системы оркестрации.
- Образ сервиса содержит все зависимости и не требует специальной (зависящей от сервиса) подготовки хоста.
- Сервисы взаимодействуют друг с другом через протоколы, не зависящие от технологии реализации сервисов.
- Сервисы могут быть написаны на нескольких различных технологических стеках.
- Сервисы могут иметь свою БД, но не имеют прямого доступа к БД других сервисов.
- Для взаимодействия сервисов активно используется асинхронный обмен сообщениями (messaging).
- Кроме системы оркестрации для работы с сервисами создана, поддерживается и развивается отдельной командой развитая (как внутренний продукт) инфраструктурная платформа микросервисов, обеспечивающая их разработку, развертывание (CI/CD), исполнение и управление (мониторинг, диагностика, и т. п.).
- Инфраструктурная платформа разрабатывается с применением практик Infrastructure as a Code.
- Создание нового сервиса и его интеграция с другими по синхронным/асинхронным каналам — дешевая автоматизированная в платформе операция (< 1 ч*ч), не требующая участия кого-либо, кроме прикладного программиста.
- Для всех сервисов на уровне платформы обеспечено обнаружение зависимостей, т.к что сервису нужно знать только логическое имя другого сервиса.
- Разрешением зависимостей можно управлять в runtime, отделяя части трафика по признакам на отдельные экземпляры (QoS), или пропуская через промежуточные прокси-сервисы.
- Для всех сервисов на уровне платформы обеспечено централизованное унифицированное журналирование, не требующее работы специалистов при добавлении нового сервиса.
- Для всех сервисов на уровне платформы обеспечено централизованное унифицированное конфигурирование, не требующее работы специалистов при добавлении нового сервиса.
- Для всех сервисов на уровне платформы обеспечен централизованный унифицированный мониторинг доступности и здоровья, не требующее работы специалистов при добавлении нового сервиса.
- Для всех сервисов на уровне платформы обеспечен централизованный унифицированный мониторинг, сбор и анализ технических и бизнес-метрик, включая производительность, не требующее работы специалистов при добавлении нового сервиса.
- Прикладной программист может самостоятельно, дешево и просто добавить атрибут в журнал, по которому будет возможен поиск и метрику, по которой возможно создание графиков и алертов.
- Обеспечена отладочная/диагностическая трассировка вызовов от входа через все синхронно вызываемые сервисы до БД включительно.
- Сервисы обновляются по отдельности или малыми группами.
- Работает по несколько экземпляров каждого сервиса, нагрузка перераспределяется между ними.
- Одновременно может работать несколько разных (близких) версий сервиса.
- Сервисы сами обновляют необходимые им структуры данных.
- Не используется никаких распределенных транзакций, вместо них — саги, eventual consistency, идемпотентные операции, протоколы отката и т. п. паттерны.
- Сервисы тестируются по отдельности.
- Обновления системы проходят с нулевым простоем.
- Сбой отдельного узла не оказывает значимого влияния на функционирование и доступность системы (практика chaos monkey).
- В случае сбоя сервис быстро останавливается (а не виснет) и система оркестрации его перезапускает.
- Для тестирования сервиса может быть собрана группа сервисов из одной (или нескольких одноименных) ветки-на-фичу (feature branch).
- Отдельные стенды для тестирования/демонстрации системы или фрагмента системы из нескольких сервисов создаются платформой быстро, дешево, и без участия специалистов.
- Перенос нужных версий БД с одного стенда на другой производится быстро, дешево, и без участия специалистов, местами — автоматически с зачисткой чувствительных данных.
- Обновления сервисов и инфраструктуры описано кодом и корректность этих кодов обновления автоматически тестируется на тестовых стендах (в delivery pipeline).
- Для сервисов проводятся автоматические тесты на соблюдение контракта платформы.
- Для сервисов автоматически строится фактическая диаграмма взаимодействия.
- Для всех сервисов есть гарантированно точные описания интерфейсов (REST, Events) и контрактов (JSON schema, etc), обновляемые не вручную отдельно, а как неизбежная часть цикла разработки.
- Для каждого поддерживаемого технологического стека заготовлен проект-стартер, позволяющий создать болванку корректно работающего сервиса, не делающего ничего, за 5 минут.
- Новая команда может подключиться к разработке нового сервиса за один день, прогнать через тесты и выпустить его на PROD.
- Canary releases. Для новых версий сервисов разворачивается небольшое число экземпляров, автоматически контролируется успешность вызовов к ним и при наличии большого числа ошибок или выходов за SLA версия откатывается и автоматически ставится дефект.
- Для сервисов определены и контролируются автоматически контракты НФТ — производительность (задержка, пропускная способность), ресурсоемкость.
- Сервисы активно используют паттерны для обработки отказов смежных сервисов — fallback, повторы вызовов, таймауты, и т. п.
- Сервисы толерантны к незначительным изменениям форматов своих зависимостей (добавление атрибутов и т. п.).
- Все сервисы могут работать в тестовом режиме, когда отдельные зависимости не требуются и заменяются встроенными заглушками c тестовыми данными.
- На уровне платформы есть механизмы контроля содержимого всех входящих/исходящих запросов и сообщений для любого сервиса.
- Количество экземпляров сервиса может автоматически меняться в зависимости от нагрузки.
- Количество хостов кластера системы оркестрации может автоматически меняться в зависимости от нагрузки.
- Для отдельных экземпляров или для сервиса в целом можно во время выполнения менять конфигурационные параметры (например, менять детализацию журналирования) и выдавать команды обслуживания (например, сбрасывать кеши).
- Платформа предоставляет готовые библиотеки/средства для решения типичных задач взаимодействия сервисов (транзакции-саги, передача реплик данных, автоматическое создание очередей, и т. п.).
- В любой момент времени у каждого сервиса есть одна небольшая команда-владелец, отвечающая за него включая PROD (хотя могут быть изменения и от других команд и выделенная служба эксплуатации 1-2 линии).
- Клиентские приложения также модульны (micro frontends) и на них распространяется большинство вышеперечисленных принципов и требований.