Реализовать микросервис на Golang, который позволяет понять во сколько потоков можно парсить определенный сайт без ошибок (нагрузочное тестирование).
Сервису на вход приходит поисковая строка, например “playstation купить”. Из поисковой выдачи Яндекса (готовый парсер тут) получаем список урлов. Далее для каждого урла нужно провести небольшой бенчмарк -- сколько параллельных запросов с одного IP этот урл выдерживает без ошибок. Максимальное время ответа - до 3 секунд. Ответом на исходный GET должна быть мапа “хост” => “рекомендуемое количество одновременных потоков”.
Обязательные моменты, которые должны быть реализованы:
- сервис должен быть обернут в docker
- взаимодействие через один эндпоинт GET /sites?search=foobar
- с непрогретым кэшом сервис должен отвечать не дольше 30 сек.
- настройка параметров через конфиг
Два http сервиса, но можно сделать монолитом. По методологии Clean Architecture (domain-app-infra-inter), по образцу monolith-microservice-shop
Основной, service, ловит /sites?search= запросы, дергает внутренний сервис для выкачивания yandex-страниц, парсинга и дергает по каждому URL второй сервис - checker. Содержит внутренний кэш на sync.Map. Если после парсинга yandex-страницы по каким-то URL нет статистики в кэше, то дергает по ним checker. По той статистике что есть checker не вызывается. Работает с ограничением ответа в 3 секунды, если за 3 секунды от яндекса или checker не пришел ответ, то отправляет клиенту все что смог собрать на момент таймаута.
Checker это http сервис, который держит несколько открытых http-клиентов, получает url для тестирования и запускает запросы через своих клиентов одновременно. Содержит внутренний кэш. Получив url от service выполняет нагрузочное тестирование и отдает результат в service. Если service уже отвалился по таймауту все равно продолжает работать, через http-callback обновляя кэш в первом сервисе.
Оба сервиса содержат внутренний кэш, возможно надо поменять на внешний, например на Redis чтобы checker клал результаты для service асинхронно.
Конфигурация через env-переменные:
Service:
TIMEOUT
- сколько ждать checkerSERVICE_ADDR
- на каком порту запускатьCHECKER_URL
- адрес checkerYANDEX_FETCHERS
- количество одновременно работающих Yandex-fetchers
Checker:
TIMEOUT
- сколько ждать сайтCHECKER_ADDR
- на каком порту пускатьCHECKER_FETCHERS
- сколько одновременных клиентов нагружать на страницыSERVICE_URL
- http callback
Построено на Makefile и docker-compose
make
- компилит cmd/service и cmd/checker в директорию проектаmake run1
иmake run2
запускают service и checker локальноmake docker
- собирает docker imagesmake up
иmake down
- запускают и гасят docker composemake test
- запуск curl теста
Сайты тестируются под нагрузкой не сразу, фактически ставятся в очередь. Если в течение 3 секунд checker не успеет отработать, то клиенту вернется все что есть в кэше и что успел checker натестировать. Но горутины, запущенные в ответ на http-запрос продолжат работать и отправлять сайты на тестирование. Если по тому же самому хосту обратиться в следующий раз, то он возьмет статистику из кэша, т.к. ее подготовит checker.