Skip to content

rAch-kaplin/MetricsService

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Сервис сбора и обработки метрик (MetricsService)

MetricsService — учебно-практический проект, реализованный в рамках программы Курса молодого бойца (КМБ) стажировки в HADAL Project. Этот сервис, предназначен для сбора, хранения и предоставления рантайм-метрик. Проект включает в себя два ключевых компонента: Агент для сбора данных и Сервер для их обработки и хранения. Система поддерживает обмен данными по протоколам REST API и gRPC, обеспечивая гибкость, надежность и безопасность.


Оглавление

  1. Ключевые возможности
  2. Архитектура приложения: Трёхуровневый подход 🏛️
  3. API Документация
  4. Конфигурация
  5. Сборка, запуск и тесты

Ключевые возможности

  • Два типа метрик: Поддержка метрик типа gauge (значение с плавающей точкой) и counter (целочисленный счётчик).
  • Гибкий транспорт: Взаимодействие между агентом и сервером по протоколам REST API и gRPC.
  • Множественные хранилища: Сервер может хранить данные в оперативной памяти, в файле на диске или в СУБД PostgreSQL.
  • Пакетная обработка: Возможность отправки и обновления метрик пачками (batch updates) для снижения сетевой нагрузки.
  • Безопасность:
    • Целостность данных: Подпись запросов и ответов с помощью SHA-256 HMAC.
    • Контроль доступа: Ограничение доступа к серверу на основе IP-адреса агента (проверка на вхождение в доверенную подсеть).
  • Производительность:
    • Параллельная отправка: Агент использует паттерн Worker Pool для контроля интенсивности отправки метрик (rate limit).
    • Эффективное сжатие: Поддержка сжатия Gzip для тела запросов и ответов.
    • Быстрая сериализация: Использование easyjson для ускоренной обработки JSON.
  • Надежность:
    • Механизм Retry: Автоматические повторные попытки при сбоях сети или временной недоступности БД с нарастающей задержкой (Exponential Backoff).
    • Корректное завершение: Graceful Shutdown для безопасной остановки сервера и агента с сохранением накопленных данных.
  • Гибкая конфигурация: Настройка всех ключевых параметров через флаги командной строки и переменные окружения.

Архитектура приложения: Трёхуровневый подход 🏛️

Сервис построен по классической и очень эффективной трёхуровневой архитектуре. Этот подход помогает разделить логику, сделать код чище, проще в поддержке и, что самое главное, — невероятно удобным для тестирования. 🧪

🗺️ 1. Внешний слой (Services / Presentation Layer)

Это "лицо" нашего приложения. Он отвечает за всё взаимодействие с внешним миром.

  • Задача: Принимать запросы (по HTTP или gRPC), разбирать их, проверять и отдавать ответы.
  • Как работает: Этот слой получает, например, JSON-запрос, превращает его в понятную для нашего приложения внутреннюю структуру (модель) и передаёт дальше на средний уровень — Usecase. Получив ответ от Usecase, он делает обратное преобразование: из внутренней структуры в JSON или Protobuf-ответ и отправляет его клиенту.
  • Конвейер Middleware: Прежде чем запрос дойдёт до основного обработчика (хендлера), он проходит через цепочку промежуточного ПО:
    • WithLogging 📝: Записывает в лог всю важную информацию о каждом запросе: URI, метод, статус ответа, время выполнения и размер.
    • WithGzipCompress 📦: Проверяет, поддерживает ли клиент сжатие (gzip), и сжимает ответ.
    • WithHashing 🔐: Проверяет подпись (HashSHA256) входящего запроса и подписывает ответ.
    • WithTrustedSubnet 🛡️: Проверяет IP-адрес клиента (X-Real-IP) и пропускает только те, что пришли из доверенной подсети.

🧠 2. Средний слой (Usecases / Business Logic Layer)

Это "мозг" приложения. Здесь живёт вся основная бизнес-логика.

  • Задача: Оркестрировать выполнение бизнес-задач. Например, "получить метрику", "обновить пачку метрик".
  • Как работает: Usecase получает команду от внешнего слоя. Он не знает ничего про JSON или HTTP. Его задача — вызвать нужные методы у внутреннего слоя (Repository), чтобы получить данные, возможно, как-то их обработать и вернуть результат.

💾 3. Внутренний слой (Repository / Data Access Layer)

Слой отвечает за хранение и извлечение информации.

  • Задача: Выполнять конкретные CRUD-операции (Create, Read, Update, Delete) с данными.
  • Как работает: Repository реализует интерфейсы, которые определены для Usecase (например, MetricGetter). Он знает всё о том, как работать с конкретным хранилищем: как написать SQL-запрос к PostgreSQL, как прочитать данные из файла или как сложить их в map в памяти.

Ключевое преимущество архитектуры — тестируемость. Благодаря такому разделению, особенно тому, что Usecase зависит от интерфейсов, мы можем легко тестировать бизнес-логику, "подменяя" (mocking) реальный репозиторий на его имитацию (мок) без запуска базы данных.


API Документация

REST API

GET /

Возвращает HTML-страницу со списком всех актуальных метрик в виде таблицы.

GET /ping

Проверяет доступность соединения с базой данных PostgreSQL.

  • 200 OK: Соединение успешно установлено.
  • 500 Internal Server Error: Ошибка соединения с БД.

POST /update

Обновляет одну метрику, переданную в теле запроса в формате JSON. Возвращает обновленный объект метрики.

  • Тело запроса: {"id":"some_metric","type":"gauge","value":10.5}
  • Тело ответа: {"id":"some_metric","type":"gauge","value":10.5}

POST /updates

Выполняет пакетное обновление нескольких метрик, переданных в виде JSON-массива.

  • Тело запроса: [{"id":"m1","type":"gauge","value":1.2},{"id":"m2","type":"counter","delta":10}]
  • Ответ: 200 OK.

POST /value

Получает одну метрику, переданную в теле запроса в формате JSON. Возвращает объект метрики с актуальным значением.

  • Тело запроса: {"id":"some_metric","type":"gauge"}
  • Тело ответа: {"id":"some_metric","type":"gauge","value":10.5}

Устаревшие эндпоинты

  • POST /update/{mType}/{mName}/{mValue}
  • GET /value/{mType}/{mName}

gRPC API

Сервис также предоставляет gRPC интерфейс для более эффективного взаимодействия. Полное описание методов доступно в .proto файле.


Конфигурация

Приоритет параметров: переменная окружения > флаг командной строки > значение по умолчанию.

Сервер

Флаг Переменная окружения По умолчанию Описание
-a ADDRESS localhost:8080 Сетевой адрес и порт для запуска HTTP-сервера.
-g GRPC_ADDRESS localhost:8081 Сетевой адрес и порт для запуска gRPC-сервера.
-i STORE_INTERVAL 300 Интервал в секундах для сохранения метрик в файл (0 — синхронная запись).
-f FILE_STORAGE_PATH /tmp/metrics-db.json Полный путь к файлу для хранения метрик.
-r RESTORE true Загружать ли метрики из файла при старте сервера.
-d DATABASE_DSN "" Строка подключения к PostgreSQL (e.g., postgres://user:pass@host/db).
-k KEY "" Ключ для вычисления и проверки SHA256-хеша.
-t TRUSTED_SUBNET "" Доверенная подсеть в формате CIDR для проверки IP-адреса агента.

Агент

Флаг Переменная окружения По умолчанию Описание
-a ADDRESS localhost:8080 Адрес и порт HTTP-сервера для отправки метрик.
-g GRPC_ADDRESS localhost:8081 Адрес и порт gRPC-сервера для отправки метрик.
-p POLL_INTERVAL 2 Частота сбора метрик в секундах.
-r REPORT_INTERVAL 10 Частота отправки метрик на сервер в секундах.
-l RATE_LIMIT 10 Количество воркеров для одновременной отправки метрик.
-k KEY "" Ключ для вычисления SHA256-хеша.

Сборка, запуск и тесты

Основные команды

  • make build - собрать бинарные файлы агента и сервера.
  • make server - собрать только сервер.
  • make agent - собрать только агент.
  • make test - запустить все юнит-тесты.
  • make bench - запустить бенчмарки.
  • make lint - запустить статический анализатор кода golangci-lint.
  • make clean - удалить собранные бинарные файлы.

Пример запуска

  1. Сборка:

    make build
  2. Запуск сервера (пример с PostgreSQL):

    export DATABASE_DSN="postgres://postgres:postgres@postgres:5432/mipt?sslmode=disable"
    ./cmd/server/server -a localhost:9090
  3. Запуск агента:

    ./cmd/agent/agent -a localhost:9090

About

The learning project for this course https://courses.mipt.ru/course/view/89

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors