Микросервисы: опыт использования в нагруженном...
TRANSCRIPT
Микросервисы: опыт использования в нагруженном проектеВадим Мадисон М-Тех
• Услуги системной интеграции, начиная от разработки технологических решений и заканчивая доставкой видео-сигнала до конечного пользователя
• Интернет-видеоплатформа для каналов МатчТВ и НТВ-ПЛЮС
• 300 000 одновременных пользователей
• > 1 000 000 уникальных посетителей в сутки
• Отдаем контента до 300 Тб/час
Про что эта история?
История про …• Рост проекта • Развитие • Переосмысление работы системы и отдельных компонентов
История про …
Масштабирование
Пройденный путь
Начало времен• 2 сервера в docker-кластере • DB запускается на тех же машинах, в контейнерах • Выделенного хранилища как такового нет • Инфраструктура минимальна
Docker TeamCity
Середина пути• 80 серверов в docker-кластере • Хранилище на базе CEPH • DB запускается на отдельных серверах • Пересмотр взаимодействия между сервисами • Выделенный мониторинг
Наши дни• Несколько сотен серверов в docker-кластере • Сотни запущенных микросервисов • Выделение сервисов в отдельные зоны • Кластеризация шин обмена сообщениями между сервисами
Транспорт
Транспорт
protobuf → gRPC → JSON
protobufПлюсы • Достаточно компактен • Есть быстрые реализации • Условно типизирован
Минусы • протокол становится
“проприетарным” • требуется поддерживать в актуальном состоянии утилиты для обращению к сервису
protobufПлюсы • Достаточно компактен • Есть быстрые реализации • Условно типизирован
Минусы • протокол становится
“проприетарным” • требуется поддерживать в актуальном состоянии утилиты для обращения к сервису
Транспорт
protobuf → gRPC → JSON
Docker TeamCity
gRPCПлюсы • HTTP/2 • Эффективность передачи • Работает из коробки • Поддержка основных серверных языков • Поддержка основных клиентских языков
Минусы • Вещь в себе • Сложность реализации собственной логики • Доступ к логам через собственные обертки и парсеры • Сложность работы в динамичной среде
gRPCПлюсы • HTTP/2 • Эффективность передачи • Работает из коробки • Поддержка основных серверных языков • Поддержка основных клиентских языков
Минусы • Вещь в себе • Сложность реализации собственной логики • Доступ к логам через собственные обертки и парсеры • Усиливает зависимости между сервисами • Сложно версионируется
Транспорт
protobuf → gRPC → JSON
Docker TeamCity JSON
JSONПлюсы • “Можно” HTTP/2 • Есть очень быстрые реализации • Поддержка повсеместно • Не требуется разрабатывать дополнительный инструментарий • Позволяется работать с
“частью данных”
JSONПлюсы • “Можно” HTTP/2 • Есть очень быстрые реализации • Поддержка повсеместно • Не требуется разрабатывать дополнительный инструментарий • Позволяется работать с
“частью данных”
Минусы • Не компактен • Не типизирован
Версионирование протокола
Версионирование протокола
V1,V2,… → V1 + schema
Версионирование протокола
V1,V2,… → V1 + schema
/api/v1/content /api/v2/content → /api/v1/content + JSON Schema v1.X /api/v3/content
{ "id": "507f1f77bcf86cd7994390", "projectId": "507f1f77bcf86cd7994390", "content": "broadcast", "name": "Жопоног - Газмяз", "date" : { "start": "2005-08-09T18:31:42-03:30", "end": "2005-08-09T18:31:42-03:30" }, "source": "http://.../playlist.m3u8", "extra": { "videoType": "хоккей", "description": "Чемпионат мира по гребной травле тараканов" }, "listeningStatus": "fail", "status": "enabled"}
{ "id": "507f1f77bcf86cd7994390", "projectId": "507f1f77bcf86cd7994390", "content": "broadcast", "name": "Жопоног - Газмяз", "date" : { "start": "2005-08-09T18:31:42-03:30", "end": "2005-08-09T18:31:42-03:30" }, "source": "http://.../playlist.m3u8", "extra": { "videoType": "хоккей", "description": "Чемпионат мира по гребной травле тараканов ;)" }, "listeningStatus": "fail", "status": "enabled"}
{ "$schema": "…", "type": "object", "properties": { "id": { "type": "string" }, "content": { "type": "string" }, "date": { "type": "object", "properties": { "start": { "type": "string" }, "end": { "type": "string" } }, "required": ["start","end"] }, "source": { "type": "string" }, "status": { "type": "string" }, … }, "required": ["id", "content", "date", "status"]}
{ "id": "507f1f77bcf86cd7994390", "content": "broadcast", "date" : { "start": "2005-08-09T18:31:42-03:30", "end": "2005-08-09T18:31:42-03:30" }, "status": "enabled"}
{ "$schema": "…", "type": "object", "properties": { "id": { "type": "string" }, "content": { "type": "string" }, "date": { "type": "object", "properties": { "start": { "type": "string" }, "end": { "type": "string" } }, "required": ["start","end"] }, "source": { "type": "string" }, "status": { "type": "string" }, … }, "required": ["id", "content", "date", "status"]}
Стабильность работы
Docker TeamCity JSON Grafana
Выводы• Основная проблема — частично работающий сервис • Мертвый сервис - хорошо! • Каждый сервис должен знать свой лимит (Rate limit)! • Защита - паттерн Circuit Breaker
Выводы• Основная проблема — частично работающий сервис • Мертвый сервис — хорошо! • Каждый сервис должен знать свой лимит (Rate limit)! • Защита - паттерн Circuit Breaker
Выводы• Основная проблема — частично работающий сервис • Мертвый сервис — хорошо! • Каждый сервис должен знать свой лимит (Rate limit)! • Защита - паттерн Circuit Breaker
Выводы• Основная проблема — частично работающий сервис • Мертвый сервис — хорошо! • Каждый сервис должен знать свой лимит (Rate limit)! • Защита — паттерн Circuit Breaker
Docker TeamCity JSON Grafana
Hystrix
Исполнение запроса
1 2 3
4 5
Docker TeamCity JSON Grafana
HystrixAppdash
Docker TeamCity JSON Grafana
Hystrix
общее время
общее время
Обращение к БДвнутри сервиса
TraceID: 19502dcb3e187d615eacf73a0ba1bfe0
Docker TeamCity JSON Grafana
HystrixOpentracing
Логирование
Docker TeamCity JSON Grafana
HystrixOpentracingElastic + Kibana
Логирование: сбор логов
Логирование• добавляем TraceID в логи • строим Dashboard фильтром по TraceID • динамический DEBUG MODE
Логирование• добавляем TraceID в логи • строим Dashboard фильтром по TraceID • динамический DEBUG MODE
Агрегирование ошибок
Docker TeamCity JSON Grafana
HystrixOpentracingElastic + Kibana
Sentry
Масштабирование
Docker TeamCity JSON Grafana
HystrixOpentracingElastic + Kibana
Sentry Nomad
Docker TeamCity JSON Grafana
HystrixOpentracingElastic + Kibana
Sentry Consul VaultNomad
Docker TeamCity JSON Grafana
HystrixOpentracingElastic + Kibana
Sentry Consul VaultKubernetes
Стандартизация: RAM-CPU-NET
Стандартизация: R3-C2-N1
Стандартизация: матрица размерностей
CPU RAM NET
C1 = 500 MHz R1 = 128 MB N1 = 10 Mb
C2 = 1000 MHz R2 = 256 MB N2 = 100 Mb
C3 = 3000 Mhz R3 = 512 MB N3 = 1 Gb
Стандартизация
•N1C3R1 → [10 Mb] [3000 MHz] [128 MB] •N1C2R3 → [10 Mb] [1500 MHz] [1 GB]
Стандартизация
•N1C3R1 → [10 Mb] [3000 MHz] [128 MB] •N1C2R3 → [10 Mb] [1000 MHz] [1 GB]
Подготовка: тип масштабируемости• Сервис полностью независим → тестируем предел для одного инстанса → тестируем 2 инстанса, чтобы проверить линейность
• Масштабируемость зависит от внешних ресурсов → при нагрузочном тестировании проводим
несколько раундов тестирования с увеличением количества инстансов
• Масштабируемость ограничена определенным лимитом → порог указывается в точке конфигурирования сервиса
Подготовка: тип масштабируемости• Сервис полностью независим → тестируем предел для одного инстанса → тестируем 2 инстанса, чтобы проверить линейность
• Масштабируемость зависит от внешних ресурсов → при нагрузочном тестировании проводим
несколько раундов тестирования с увеличением количества инстансов
• Масштабируемость ограничена определенным лимитом → порог указывается в точке конфигурирования сервиса
Подготовка: тип масштабируемости• Сервис полностью независим → тестируем предел для одного инстанса → тестируем 2 инстанса, чтобы проверить линейность
• Масштабируемость зависит от внешних ресурсов → при нагрузочном тестировании проводим
несколько раундов тестирования с увеличением количества инстансов
• Масштабируемость ограничена определенным лимитом → порог указывается в точке конфигурирования сервиса
Подготовка: нагрузочное тестирование
Docker JSON Grafana
HystrixOpentracingElastic + Kibana
Sentry Consul VaultKubernetes Gitlab CI
TeamCity
Рекомендации• Начинайте разработку сразу с использованием системы оркестрации • В каждый момент времени помните, что каждого инстанса сервиса должно быть не меньше 2-х • Шина сообщений, блокировки и очереди - наше все • Не нужно пытаться поднять/починить сервис - нужно отстрелить его и потом попробовать понять, что не так • Собирайте метрики и работайте с ними • Выдавайте алерты только там, где требуется реакция
Рекомендации• Начинайте разработку сразу с использованием системы оркестрации • В каждый момент времени помните, что каждого инстанса сервиса должно быть не меньше 2-х • Шина сообщений, блокировки и очереди - наше все • Не нужно пытаться поднять/починить сервис - нужно отстрелить его и потом попробовать понять, что не так • Собирайте метрики и работайте с ними • Выдавайте алерты только там, где требуется реакция
Рекомендации• Начинайте разработку сразу с использованием системы оркестрации • В каждый момент времени помните, что каждого инстанса сервиса должно быть не меньше 2-х • Шина сообщений, блокировки и очереди — наше все • Не нужно пытаться поднять/починить сервис - нужно отстрелить его и потом попробовать понять, что не так • Собирайте метрики и работайте с ними • Выдавайте алерты только там, где требуется реакция
Рекомендации• Начинайте разработку сразу с использованием системы оркестрации • В каждый момент времени помните, что каждого инстанса сервиса должно быть не меньше 2-х • Шина сообщений, блокировки и очереди — наше все • Не нужно пытаться поднять/починить сервис — нужно отстрелить его и потом попробовать понять, что не так • Собирайте метрики и работайте с ними • Выдавайте алерты только там, где требуется реакция
Рекомендации• Начинайте разработку сразу с использованием системы оркестрации • В каждый момент времени помните, что каждого инстанса сервиса должно быть не меньше 2-х • Шина сообщений, блокировки и очереди — наше все • Не нужно пытаться поднять/починить сервис — нужно отстрелить его и потом попробовать понять, что не так • Собирайте метрики и работайте с ними • Выдавайте алерты только там, где требуется реакция
Рекомендации• Начинайте разработку сразу с использованием системы оркестрации • В каждый момент времени помните, что каждого инстанса сервиса должно быть не меньше 2-х • Шина сообщений, блокировки и очереди — наше все • Не нужно пытаться поднять/починить сервис — нужно отстрелить его и потом попробовать понять, что не так • Собирайте метрики и работайте с ними • Выдавайте алерты только там, где требуется реакция
Спасибо!Вадим Мадисон
М-Тех