4. О чем поговорим
● Когда стоит подумать о микросервисной
архитектуре
● Декомпозиция монолитных приложений
5. О чем поговорим
● Когда стоит подумать о микросервисной
архитектуре
● Декомпозиция монолитных приложений
● Требования к приложению
6. О чем поговорим
● Когда стоит подумать о микросервисной
архитектуре
● Декомпозиция монолитных приложений
● Требования к приложению
● Отказоустойчивость и стабильность
микросервисов
21. ● Независимая разработка – технологии, команды и
процессы могут быть совершенно разными
● Независимый деплой
Преимущества микросервисов
22. Преимущества микросервисов
● Независимая разработка – технологии, команды и
процессы могут быть совершенно разными
● Независимый деплой
● Один упал, остальное работает
23. Преимущества микросервисов
● Независимая разработка – технологии, команды и
процессы могут быть совершенно разными
● Независимый деплой
● Один упал, остальное работает
● Модульность – просто включитьвыключить, легко
удалять код, не такое страшное легаси
24. Преимущества микросервисов
● Независимая разработка – технологии, команды и
процессы могут быть совершенно разными
● Независимый деплой
● Один упал, остальное работает
● Модульность – просто включитьвыключить, легко
удалять код, не такое страшное легаси
● Децентрализованное управление данными
26. ● Инфраструктура усложнилась – нужно время на
доработку и более опытная команда для ее
поддержки
Микросервисы: trade-offs
27. ● Инфраструктура усложнилась – нужно время на
доработку и более опытная команда для ее
поддержки
● Появилось больше точек отказа
Микросервисы: trade-offs
28. ● Инфраструктура усложнилась – нужно время на
доработку и более опытная команда для ее
поддержки
● Появилось больше точек отказа
● CPU-вызовы заменились на Network-вызовы: выросла
нагрузка на сеть, вызовы стали медленнее и
вероятность их отказа выросла
Микросервисы: trade-offs
29. Микросервисы: trade-offs
● Инфраструктура усложнилась – нужно время на
доработку и более опытная команда для ее
поддержки
● Появилось больше точек отказа
● CPU-вызовы заменились на Network-вызовы: выросла
нагрузка на сеть, вызовы стали медленнее и
вероятность их отказа выросла
● Eventual consistency – нужно подождать, чтобы
увидеть результаты изменений
31. ● Небольшая кодовая база, простой/утилитарный
проект, нет планов по расширению
Микрослужбы: когда еще рано
32. ● Небольшая кодовая база, простой/утилитарный
проект, нет планов по расширению
● Трудности обновления инфраструктуры
перевешивают плюсы от микросервисов
Микрослужбы: когда еще рано
33. Микрослужбы: когда еще рано
● Небольшая кодовая база, простой/утилитарный
проект, нет планов по расширению
● Трудности обновления инфраструктуры
перевешивают плюсы от микросервисов
● У вас и так все в порядке: быстро разрабатываете;
быстро выкладываете в продакшен; пишите
красивый, модульный код
35. ● Появилась определенное требование к безопасности,
стабильности и скорости разработки
Микрослужбы: когда стоит подумать
36. ● Появилась определенное требование к безопасности,
стабильности и скорости разработки
● Текущий фреймворк плохо подходит под новые
задачи
Микрослужбы: когда стоит подумать
37. ● Появилась определенное требование к безопасности,
стабильности и скорости разработки
● Текущий фреймворк плохо подходит под новые
задачи
● Большая команда и много кода – долгие релизы,
частые merge-конфликты
Микрослужбы: когда стоит подумать
38. ● Появилась определенное требование к безопасности,
стабильности и скорости разработки
● Текущий фреймворк плохо подходит под новые
задачи
● Большая команда и много кода – долгие релизы,
частые merge-конфликты
● Сильная нагрузка на определенный функционал, его
нужно либо переписать либо масштабировать
Микрослужбы: когда стоит подумать
39. Микрослужбы: когда стоит подумать
● Появилась определенное требование к безопасности,
стабильности и скорости разработки
● Текущий фреймворк плохо подходит под новые
задачи
● Большая команда и много кода – долгие релизы,
частые merge-конфликты
● Сильная нагрузка на определенный функционал, его
нужно либо переписать либо масштабировать
● Долгие деплои, связынные с большим количеством
кода и различных обслуживающих операций
(скриптов)
46. ● CPU-bound vs IO-bound
Выбор фреймворка под конкретный
сервис/задачи
47. ● CPU-bound vs IO-bound
● Стабильность и безопасность
Выбор фреймворка под конкретный
сервис/задачи
48. ● CPU-bound vs IO-bound
● Стабильность и безопасность
● Удобство разработки
Выбор фреймворка под конкретный
сервис/задачи
49. ● CPU-bound vs IO-bound
● Стабильность и безопасность
● Удобство разработки
● Количество доступных «батареек»
Выбор фреймворка под конкретный
сервис/задачи
50. Выбор фреймворка под конкретный
сервис/задачи
● CPU-bound vs IO-bound
● Стабильность и безопасность
● Удобство разработки
● Количество доступных «батареек»
● Производительность
51. Выбор фреймворка под конкретный
сервис/задачи
● CPU-bound vs IO-bound
● Стабильность и безопасность
● Удобство разработки
● Количество доступных «батареек»
● Производительность
● Поддержка (LTS релизы)
54. Совет №1: чем стабильнее и
функциональнее будет фреймворк, тем
меньше головной боли вас ожидает в
будущем.
Что выбрать?
55. Совет №1: чем стабильнее и
функциональнее будет фреймворк, тем
меньше головной боли вас ожидает в
будущем.
Совет №2: не обязательно выбирать
микрофреймворк для создания
микросервиса.
Что выбрать?
57. «Синхронные» – используют модель workers
pool, каждый worker приложения работает над
одним запросом в единицу времени не
прерываясь, оперируют функциями: Django,
Flask, Falcon и т.д.
Типы web-фреймворков
58. «Синхронные» – используют модель workers
pool, каждый worker приложения работает над
одним запросом в единицу времени не
прерываясь, оперируют функциями: Django,
Flask, Falcon и т.д.
«Асинхронные» – используют паттерн Eventloop,
оперируют корутинами: Tornado, aiohttp, Sanic и
т.д.
Типы web-фреймворков
60. ● CRUD сервисы для работы с реляционными СУБД:
Синхронный фреймворк
61. ● CRUD сервисы для работы с реляционными СУБД:
○ Удобные ORM с богатым функционалом
Синхронный фреймворк
62. ● CRUD сервисы для работы с реляционными СУБД:
○ Удобные ORM с богатым функционалом
○ Удобные инструменты для создания и проведения
миграций
Синхронный фреймворк
63. ● CRUD сервисы для работы с реляционными СУБД:
○ Удобные ORM с богатым функционалом
○ Удобные инструменты для создания и проведения
миграций
○ Ограничения psycopg2 при работы с асинхронными
запросами (autocommit, set_client_encoding, executemany,
large objects, named cursors)
Синхронный фреймворк
64. ● CRUD сервисы для работы с реляционными СУБД:
○ Удобные ORM с богатым функционалом
○ Удобные инструменты для создания и проведения
миграций
○ Ограничения psycopg2 при работы с асинхронными
запросами (autocommit, set_client_encoding, executemany,
large objects, named cursors)
○ aiomysql – еще в alpha
Синхронный фреймворк
65. ● CRUD сервисы для работы с реляционными СУБД:
○ Удобные ORM с богатым функционалом
○ Удобные инструменты для создания и проведения
миграций
○ Ограничения psycopg2 при работы с асинхронными
запросами (autocommit, set_client_encoding, executemany,
large objects, named cursors)
○ aiomysql – еще в alpha
● Админки и интерфейсы CMS
Синхронный фреймворк
66. ● CRUD сервисы для работы с реляционными СУБД:
○ Удобные ORM с богатым функционалом
○ Удобные инструменты для создания и проведения
миграций
○ Ограничения psycopg2 при работы с асинхронными
запросами (autocommit, set_client_encoding, executemany,
large objects, named cursors)
○ aiomysql – еще в alpha
● Админки и интерфейсы CMS
● REST поверх CRUD – за счет мощного Django Rest Framework
Синхронный фреймворк
67. ● CRUD сервисы для работы с реляционными СУБД:
○ Удобные ORM с богатым функционалом
○ Удобные инструменты для создания и проведения
миграций
○ Ограничения psycopg2 при работы с асинхронными
запросами (autocommit, set_client_encoding, executemany,
large objects, named cursors)
○ aiomysql – еще в alpha
● Админки и интерфейсы CMS
● REST поверх CRUD – за счет мощного Django Rest Framework
● Сервисы требующие повышенного отношения к безопасности
(платежи, важные пользовательские данные и т.д.)
Синхронный фреймворк
77. «Детские болячки» в асинхронном мире
● aiohttp pre 2.0 era
○ Socket leak and incorrect connection close
○ Обратно несовместимые изменения
○ Запутывающие ошибки вида "error handling response" и
"cancelled error"
78. «Детские болячки» в асинхронном мире
● aiohttp pre 2.0 era
○ Socket leak and incorrect connection close
○ Обратно несовместимые изменения
○ Запутывающие ошибки вида "error handling response" и
"cancelled error"
● pewee_async
○ Нет поддержки агрегационных запросов
○ Неправильно обрабатываются закрытые соединения
79. «Детские болячки» в асинхронном мире
● aiohttp pre 2.0 era
○ Socket leak and incorrect connection close
○ Обратно несовместимые изменения
○ Запутывающие ошибки вида "error handling response" и
"cancelled error"
● pewee_async
○ Нет поддержки агрегационных запросов
○ Неправильно обрабатываются закрытые соединения
● asyncio_redis
○ дедлок
80. Но не стоит сгущать краски
Twisted и Tornado – зрелые, стабильные,
функциональные.
95. Отказоустойчивость и стабильность
● Понятие recovery – контракт на то, как вести себя
сервису в случае ошибок, которые он может
обработать и которые не может
96. ● Понятие recovery – контракт на то, как вести себя
сервису в случае ошибок, которые он может
обработать и которые не может
● Обязательные и короткие таймауты
Отказоустойчивость и стабильность
97. ● Понятие recovery – контракт на то, как вести себя
сервису в случае ошибок, которые он может
обработать и которые не может
● Обязательные и короткие таймауты
● Circuit Breakers – не заваливать сервис запросами,
если он умирает.
Отказоустойчивость и стабильность
98. ● Понятие recovery – контракт на то, как вести себя
сервису в случае ошибок, которые он может
обработать и которые не может
● Обязательные и короткие таймауты
● Circuit Breakers – не заваливать сервис запросами,
если он умирает.
● Fail fast – лучше сразу упасть, чем ждать
Отказоустойчивость и стабильность
99. ● Понятие recovery – контракт на то, как вести себя
сервису в случае ошибок, которые он может
обработать и которые не может
● Обязательные и короткие таймауты
● Circuit Breakers – не заваливать сервис запросами,
если он умирает.
● Fail fast – лучше сразу упасть, чем ждать
● Общие клиенты вынесены в зависимости
Отказоустойчивость и стабильность
101. Отказоустойчивость и стабильность
● Обязательное логирование, метрики и мониторинг,
авторестарт
● Правильная обработка сигналов SIGTERM и SIGINT
102. Отказоустойчивость и стабильность
● Обязательное логирование, метрики и мониторинг,
авторестарт
● Правильная обработка сигналов SIGTERM и SIGINT
● Сохранение обратной совместимости в рамках одной
версии API
103. Отказоустойчивость и стабильность
● Обязательное логирование, метрики и мониторинг,
авторестарт
● Правильная обработка сигналов SIGTERM и SIGINT
● Сохранение обратной совместимости в рамках одной
версии API
● Connection pools – правильно обрабатываем
закрытые соединения, иначе zombie-service.
104. Отказоустойчивость и стабильность
● Обязательное логирование, метрики и мониторинг,
авторестарт
● Правильная обработка сигналов SIGTERM и SIGINT
● Сохранение обратной совместимости в рамках одной
версии API
● Connection pools – правильно обрабатываем
закрытые соединения, иначе zombie-service.
● Request Id – подписываем (headers) все запросы,
чтобы агрегировать логи между сервисами
106. ● Переход от вызовов функций к вызовам сервисов без
адаптации архитектуры
Классические ошибки при внедрении и
разработке микросервисов
107. ● Переход от вызовов функций к вызовам сервисов без
адаптации архитектуры
● Незафиксированные версии зависимостей
(requirements.txt)
Классические ошибки при внедрении и
разработке микросервисов
108. ● Переход от вызовов функций к вызовам сервисов без
адаптации архитектуры
● Незафиксированные версии зависимостей
(requirements.txt)
● Слишком много CPU-bound задач в асинхронных сервисах,
например json-сериализация. IO-bound в асинхронных.
Классические ошибки при внедрении и
разработке микросервисов
109. ● Переход от вызовов функций к вызовам сервисов без
адаптации архитектуры
● Незафиксированные версии зависимостей
(requirements.txt)
● Слишком много CPU-bound задач в асинхронных сервисах,
например json-сериализация. IO-bound в асинхронных.
● loop.run_in_executor не всегда спасет от проблем с
CPU-bound задачами
Классические ошибки при внедрении и
разработке микросервисов
110. ● Переход от вызовов функций к вызовам сервисов без
адаптации архитектуры
● Незафиксированные версии зависимостей
(requirements.txt)
● Слишком много CPU-bound задач в асинхронных сервисах,
например json-сериализация. IO-bound в асинхронных.
● loop.run_in_executor не всегда спасет от проблем с
CPU-bound задачами
● Использование глобальных объектов для хранения
состояния запроса в памяти асинхронного приложения
Классические ошибки при внедрении и
разработке микросервисов
111. ● Длинные последовательные цепочки запросов между
сервисами, необходимые для формирования данных.
Классические ошибки при внедрении и
разработке микросервисов
112. ● Длинные последовательные цепочки запросов между
сервисами, необходимые для формирования данных.
● «Сервис на каждый чих»
Классические ошибки при внедрении и
разработке микросервисов
113. ● Длинные последовательные цепочки запросов между
сервисами, необходимые для формирования данных.
● «Сервис на каждый чих»
● Один источник данных для всех сервисов
Классические ошибки при внедрении и
разработке микросервисов
114. ● Длинные последовательные цепочки запросов между
сервисами, необходимые для формирования данных.
● «Сервис на каждый чих»
● Один источник данных для всех сервисов
● Копипаста кода между сервисами, вместо установки
зависимостей (если у вас не монорепозиторий)
Классические ошибки при внедрении и
разработке микросервисов
115. ● Длинные последовательные цепочки запросов между
сервисами, необходимые для формирования данных.
● «Сервис на каждый чих»
● Один источник данных для всех сервисов
● Копипаста кода между сервисами, вместо установки
зависимостей (если у вас не монорепозиторий)
● Отсутствие автоматизации версионирования сервисов
(versioneer, bumpversion)
Классические ошибки при внедрении и
разработке микросервисов
116. ● Длинные последовательные цепочки запросов между
сервисами, необходимые для формирования данных.
● «Сервис на каждый чих»
● Один источник данных для всех сервисов
● Копипаста кода между сервисами, вместо установки
зависимостей (если у вас не монорепозиторий)
● Отсутствие автоматизации версионирования сервисов
(versioneer, bumpversion)
● Если где-то соединение открывается, то где-то оно должно
быть закрыто
Классические ошибки при внедрении и
разработке микросервисов
120. Интеграции со сторонними сервисами
● Правильно обрабатывать ошибки (коды ответа,
правильный recovery)
● Exponential backoff – увеличивать промежуток между
опросами экспоненциально
● Строгая валидация данных чаще всего не работает.
Активная валидация по json-schema – приводит к
проблемам, т.к. поставщики на самом деле часто меняют
API.
121. Интеграции со сторонними сервисами
● Правильно обрабатывать ошибки (коды ответа,
правильный recovery)
● Exponential backoff – увеличивать промежуток между
опросами экспоненциально
● Строгая валидация данных чаще всего не работает.
Активная валидация по json-schema – приводит к
проблемам, т.к. поставщики на самом деле часто меняют
API.
● Фильтрация данных на html и sql-injections от поставщика.
123. Designing and Deploying Microservices
https://www.nginx.com/resources/library/designing-deploying-m
icroservices/
Best Practices for Building a Microservice
Architecture
http://www.vinaysahni.com/best-practices-for-building-a-micros
ervice-architecture
В итоге: подготовьтесь теоретически