Что мы знаем о микросервисах
Intro
Авито: много сервисов и очень много связей между ними.
Вот основные проблемы от количества:
- Много разных репозиториев. Сложно менять код одновременно везде.
- Много команд пишут код, не пересекаясь с другими. Знания инкапсулируются и плохо передаются между командами. Нет единой картины. Нет человека, который бы всё знал.
- Данные фрагментарны.
Проблемы с инфраструктурой: слишком много элементов:
- Логирование
- Мониторинг
- Сборка
- Общение
- Трекер задач
- Документация
- Аааааа
Слои: service mesh, k8s, bare metal. Отдельно мониторинг и PaaS. Доклад будет как раз про него.
В платформе есть три основных части:
- Генераторы, управляются через CLI
- Агрегатор (коллектор), управляется через дашборд
- Хранилище (storage) с триггерами на определённые действия.
Стандартный конвейер разработки микросервиса
CLI-push
Создаём сервис из шаблона. Вместо первого git push
.
Долго учили разработчиков правильно начинать работу, но это всё равно становится узким местом при внедрении микросервисов. Поэтому сделали утилиту в помощь разработчикам. Утилита делает вот что:
- Создаёт сервис из шаблона.
- Разворачивает инфраструктуру для локальной разработки
- Подключает БД одной командой без конфигов.
Раньше деплой сервиса был сложный и составной.
Сделали проще: один файл app.toml
.
Базовая валидация:
- Есть докерфайл
- Есть
app.toml
- Есть документация
- Зависимости в порядке
- УКазаны правила алертов для мониторинга. Владелец сервиса сам это настраивает.
Документация
Входит:
- Описание сервиса. В двух предложениях, что сервис делает.
- Диаграмма архитектуры.
- Runbook.
- FAQ
- Описание API endpoints
- Labels — к какому продукту, функциональности и структурному подразделению относится сервис.
- Владельцы. Обычно определяем автоматически, но на всякий случай надо.
- Ревью?
Подготовка пайплайна
- Готовим репозитории
- Делаем пайплайн в Teamcity
- Выставляем права
- Ищем владельцев — вычисляем по push’ам в репозиторий.
- Одного недостаточно, ненадёжно. Ищем двух.
- Считаем количество пушей и количество кода в пуше.
- Регистрируем сервис в Atlas
- Проверяем миграции. Если они потенциально опасны, инфу в Атлас, а сервис в карантин.
Дальше
- Собираем приложение в докер-образ
- Генерируем хелмчарты для сервиса и его ресурсов
- Создаем админские тикеты на открытие портов
- Юнит-тесты, считаем покрытие кода. Результаты — в Атлас.
- Считаем ограничения по памяти и процессору.
Go + k8s + GOMAXPROCS — придётся оптимизировать производительность. Поможет библиотека automaxprocs.
Проверка
Вот что проверяем:
- API endpoints
- Их ответы соответствуют схеме
- Формат логов
- Выставление заголовков при запросах
- Выставление заголовков при отправке сообщений в шину. Тут проверяется связность сервисов.
Тесты
- Тестируем в закрытом контуре, например hoverfly.io.
- Нагрузочное тестирование — важно.
Нагрузочное тестирование показывает дельту производительности между версиями. Проверяем, что потребление соответствует заданным ограничениям.
- Слишком мало — OOM killer?
- Слишком много — оптимизировать.
Canary tests
Начинаем с очень малого процента — меньше 0,1%.
Держим от 5 минут до 2 часов.
Смотрим:
- Метрики, специфичные для языка. Например, воркеры php-fpm.
- Ошибки в Sentry
- Статусы ответов
- Время ответов — точное и среднее
- Latency
- Исключения обработанные и необработанные
- Продуктовые метрики, внезапно, тысячи их!
Squeeze testing
Тестирование через выдавливание. Нагружаем реальными пользователями один инстанс, пока он не нагрузится на 100%, «в полку». Потом добавляем +1, снова смотрим полку, вычисляем дельту. Сравниваем эти данные с данными от искусственной нагрузки.
Прод
Мониторим на продакшене.
Смотреть только на CPU — неэффективно, потому что соседи фонят. Поэтому смотрим на специфические для приложения метрики. Результаты — в Атлас.
Итого:
- CPU + RAM
- количество запросов в очереди
- время ответа
- ?
Что ещё
- Миграции, если не осталось версий сервиса ниже Х
- Обновления безопасности
- Если сервис давно не обновлялся — пересобрать для проверки
- Если метрики выходят из нормы — в карантин
Дашборд
Смотрим на всё сверху в агрегированном виде и делаем выводы.