metricinc
Сервис сбора инкрементальных метрик

Описание
Сервис для хранения метрики, инкрементируемой с заданным шагом при обращении клиента по протоколу gRPC.
Доступны следующие методы:
- SetSettings - задание начальных значений (счетчик, размер инкремента, верхняя граница счетчика)
- GetNumber - вернуть текущее значение счетчика
- IncrementNumber - увеличить счетчик на размер инкремента
Используемые библиотеки
- RPC - google.golang.org/grpc, т.к. гоняем небольшие данные, заворачивать их в JSON будет неэффективно
- KV-хранилище - github.com/boltdb/bolt, для маршаллинга можно использовать методы protobuf gRPC
- конфигурация - github.com/jessevdk/go-flags, каждый пакет прозрачно для main добавляет свои конфиги
- логи - github.com/sirupsen/logrus - есть уровни, хуки и вывод разным потребителям
Структура проекта
.
├── cmd - исходный код (main.go) бинарников проекта
│ ├── client - пример клиента
│ └── server - gRPC cервер
├── counter - Счетчик, основная математика проекта
│ └── setup - структура настроек, вынесена отдельно для использования другими пакетами
├── docker-compose.yml - используется Makefile (make up|down)
├── Dockerfile - используется Makefile (make build-docker)
├── glide.* - регистрация зависимостей для установки в vendor/
├── lib - пакеты, используемые для сборки бинарников
│ ├── boltdb - вариант kv-хранилища на основе BoltDB
│ ├── client - установка соединения с gRPC сервером и доступ к его методам
│ ├── grpcapi - gRPC сервис (тесты используют mock kvstore)
│ ├── iface - интерфейсы для использования в пакетах вместо ссылок на внешние библиотеки
│ │ ├── kvstore - интерфейс kv-хранилища
│ │ └── logger - интерфейс журналирования
│ ├── logger - вариант журналирования на основе logrus
│ ├── mocks - сгенеренный код для подмены интерфейсов в тестах
│ └── proto - описания структур protobuf
│ └── counter - описание протокола обмена с gRPC
├── LICENSE - MIT
├── Makefile - в этом файле собраны все команды, используемые при сборке (список команд: make help)
├── README.md - этот файл
├── t - тесты для контейнера docker
│ ├── test-docker.sc - сценарий обмена клиента и сервера
│ └── test-docker.want - эталон журнала обмена
└── var/data - этот каталог монтируется docker-compose для сохранения данных KV-хранилища
Зависимости
При сборке проекта используются docker-образ go, линтер и зависимости из glide.yaml
.
Использование
make test-docker
- сборка приложений в контейнер и отработка тестового сценария
make clean-docker
- удаление временных файлов и созданного docker image
make doc
- запуск http сервера с godoc документацией по исходным текстам
make help
- список доступных команд (целей Makefile)
Для локальной сборки без docker каталог проекта должен быть доступен как $GOPATH/github.com/LeKovr/metricinc
Особенности реализации
- Рестарт сервиса не влечет сброс текущих значений
- Методы чтения данных не обращаются к KV-хранилищу, оно используется только при старте и при изменении данных
- Если при сохранении данных в KV-хранилище возникает ошибка, реакция приложения зависит от наличия опции
--store_strict
- если она задана, клиенту возвращается текст ошибки. Иначе - ошибка протоколируется, но не возвращается клиенту. Если позднее ошибка записи уйдет, первое же сохранение сделает систему консистентной. На случай неустранимой аварии сервер при завершении работы пишет текущие данные в журнал (как warning), что позволяет продолжить работу с тех же значений.
- Поддерживаемые сервером опции позволяют начать работу с произвольных значений счетчика и настроек
- Клиентское приложение при выполнении любой команды возвращает JSON с текущими значениями счетчика и настроек
- Клиентская библиотека коннектится к серверу сама, чтобы не дублировать этот код в тестах. Серверная - не коннектится, чтобы ее использовать в составе других сервисов.
- работа с журналированием и KV-хранилищем производится через интерфейсы. Конкретные реализации (
logrus
и boltdb
) указаны только в обертках (lib/boltdb
и lib/logger
), которые подключаются в cmd/server/main.go
. При выборе других реализаций остальные пакеты не потребуют изменений.
- Для интеграционных тестов используется тестовый сценарий - аргументы программы client. Для каждой строки сценария производится вызов команды и результат сохраняется в файл, который потом сравнивается с эталоном. При совпадении выводится сообщение "Test completed successfully", иначе - diff с отличиями от эталона.
Примечания по test coverage
Coverage: 100.0% of statements
counter
lib/client
lib/grpcapi
lib/logger
Coverage: 0.0% of statements
counter/setup
- пакет содержит только структуру, она вынесена для пакетов, которым нужна только она
lib/iface/*
- здесь только описания интерфейсов
lib/proto/*
- здесь только описания структур protobuf
lib/mocks/*
- файлы генерит mockgen, для них можно написать тесты, если не доверяем генератору
lib/boltdb
- для сокращения тайминга проекта
TODO
Возможные расширения ТЗ при развитии проекта:
- рефакторинг тестов
- cmd/: изучить плюсы переноса кода из main в lib/ (сейчас из main легко понять, из чего состоит программа)
- int64 используется из-за уточнения задачи, м.б. стоит переделать на uint64, т.к. все числа положительные
- тесты оформить во внешнем файле (см t/test-docker.sc) и этот файл использовать при тестировании counter, lib/grpcapi, docker (нужны интерпретаторы сценария тестов для каждого случая)
- docker-compose: удалять образ первой стадии сборки
- grpc: SSL или переехать на http
- grpc: в логи об ошибках добавить идентификацию клиента
- http: добавить хэндлер, возвращающий метрики сервиса (и grpc?)
- прикрутить поиск к godoc
- сделать интерфейс и mock для пакета counter
Changes
- v1.3, Публикация на github: 3.04.18
- v1.0, Готовность проекта: 6.09.17
- Начало работ: 30.08.17
License
The MIT License (MIT), see LICENSE.
Copyright (c) 2017 Alexey Kovrizhkin lekovr@gmail.com