Перед изучением данного руководства рекомендуется ознакомиться с руководством пользователя GitlabProducer
Стек технологий: Golang, Kafka, Redis
Переменные конфига:
Переменная | Обязательность | Описание | Пример значения |
---|---|---|---|
SCHEDULING_POLL_INTERVAL | - | Интервал в секундах, который проходит между выгрузкой данных из Gitlab | 30 |
GITLAB_BASE_URL | + | URL api Gitlab | https://git.miem.hse.ru/api/v4 |
GITLAB_PRIVATE_TOKEN | + | Токен для api Gitlab | top-secret |
GITLAB_PER_PAGE_PAGINATION | - | Кол-во элементов при пагинированных запросах в Gitlab | 10 |
KAFKA_BOOTSTRAP_SERVERS | + | Брокеры Kafka через запятую | kafka-host1:9092,kafka-host2:9092 |
KAFKA_TOPIC | + | Топик Kafka в который будут отправляться сообщения | data-bus.gitlab.events |
KAFKA_LOGIN | - | Логин Kafka | user |
KAFKA_PASSWORD | - | Пароль Kafka | pass |
CACHE_TTL | - | Время хранения кэша (в минутах) | 1440 |
OPERATIONS_PER_SECOND | - | Количество запросов в секунду в gitlab | 1 |
METRICS_PORT | - | Порт для метрик | 9000 |
METRICS_URL | - | Ручка для метрик | metrics |
REDIS_ADDRESS | - | Адрес Redis | redis:6379 |
REDIS_PASSWORD | - | Пароль к Redis | password |
LOG_PORT | - | Порт для смены уровня логирования | 8002 |
LOG_LEVEL | - | Стандартный уровень логирования | info |
SCHEDULING_POLL_INTERVAL | - | Время ожидания в секундах между sink раундами | 30 |
gitlab-producer включает 4 базовых сервиса:
scheduling_service - сервис реализации синкраунда.
gitlab_service - сервис обмена данными с Gitlab
kafka_producing_service - сервис загрузки данных в Kafka
event_cache_filter - сервис кэширования событий
Основная работа gitlab-producer'а проходит внутри метода этого сервиса StartLoop. Метод организует циклическую работу синк-раундов. В начале синк-раунда создается два go-канала - для проектов(далее будем называть ch
) и пользователей (далее будем называть uch
).
Далее запускаются 4 goroutine:
pullNewProjects
- загрузка проектов при помощи gitlab_service с изменениями не ранее текущих суток и передача загруженных проектов в chsinkProjects
- для каждого проекта из ch запрашиваются новые события (при помощи gitlab-service), проверка на наличие событий в кэше (при помощи event_cache_filter). Если событие отсутствует в кэше - событий отправляется в шину (при помощи kafka_producing_service) и кэшируется (при помощи event_cache_filter)pullNewUsers
- загрузка пользователей при помощи gitlab_service и дальнейшая передача в uchsinkUsers
- для каждого пользователя из uch запрашиваются новые события (при помощи gitlab-service), проверка на наличие событий в кэше (при помощи event_cache_filter). Если событие отсутствует в кэше - событий отправляется в шину (при помощи kafka_producing_service) и кэшируется (при помощи event_cache_filter)Как только все goroutine закончат работу синк-раунд завершается и сервис уходит в сон на SCHEDULING_POLL_INTERVAL секунд (по умолчанию 30)
Основные задачи сущности -
Все методы работают по схожему алгоритму:
Отличия лишь в способе передачи выходных данных - SinkProjectMetadataToChannel и SinkUsersMetadataToChannel передают последовательно структуры в канал, в то время как GetEventsForProject и GetEventsForUser возвращают массив структур
Пример гитлаб-события:
{
"id": 1,
"title":null,
"project_id":1,
"action_name":"opened",
"target_id":160,
"target_type":"Issue",
"author_id":25,
"target_title":"Qui natus eos odio tempore et quaerat consequuntur ducimus cupiditate quis.",
"created_at":"2017-02-09T10:43:19.667Z",
"author":{
"name":"User 3",
"username":"user3",
"id":25,
"state":"active",
"avatar_url":"http://www.gravatar.com/avatar/97d6d9441ff85fdc730e02a6068d267b?s=80\u0026d=identicon",
"web_url":"https://gitlab.example.com/user3"
},
"author_username":"user3"
}
На ранних этапах тестирования сервис создавал высокую нагрузку на git.miem.hse.ru. Для уменьшения нагрузки был установлен ограничитель нагрузки, реализованный при помощи "go.uber.org/ratelimit". Он позволяет ограничивать количество отправляемых в gitlab запросов до OPERATIONS_PER_SECOND запросов в секунду.
Основная задача сущности - отправлять события в брокер Kafka. Для этого написано метод ProduceEvent.
Принцип работы:
Также, при создании экземпляра сущности kafka_producing_service запускается goroutine producerEventHandler для проверки на успешную доставку события в Kafka
Ввиду особенностей работы API-Gitlab не представляется возможным запрашивать проекты с последними изменениями не ранее предыдущего синк-раунды. API-Gitlab'а позволяет запросить проекты после определенной даты, но не времени. Для решения данной проблемы был написан сервис, позвляющий кэшировать отправленные в брокер события, для исключения дублированния данных.
Сервис является интерфейсом для работы с Redis, позволяющий записать событие и проверить на наличие.
У каждого события gitlab уникальный id, поэтому для кэширования достаточно хранить id события.
Формат записей в Redis: id_события=true
Для уменьшения затрат ресурсов ограничено время хранения кэша. По умолчанию кэш хранится 1440 минут (24 часа). Изменить это значение можно через переменную окружения CACHE_TTL
Для сбора метрик (PROMETHEUS) предусмотрен обработчик:
GET METRICS_PORT/METRICS_URL
Пример curl скрипта:
curl -X PUT localhost:9000/prometheus
Для смены логгирования по ходу работы программы предусмотрен специальный обработчик:
PUT LOG_PORT/log_level -d level=NEW_LOG_LEVEL
- обработчик для смены текущего уровня логгирования (допустимые значения NEW_LOG_LEVEL: info, debug)Пример curl скрипта:
curl -X PUT localhost:1065/log_level -d level=info