Таймауты для gRPC запросов (NodeJS)

Дмитрий Кузнецов
Дмитрий Кузнецов · 12 марта 2021
Backend

Предыстория

Однажды у одного из наших сервисов, работающего с географией, начались проблемы с чтением из базы — запросы обрабатывались, но занимали слишком много времени. Выше по цепочке потребителей этого сервиса находилась Витрина, которая, не получив ответа за установленный срок, кидала запрос повторно, что привело к лавинообразному росту нагрузки и падению сервиса.

Проблема

Для наших сервисов на gRPC не был настроен механизм таймаутов.

Анализ

Нам было необходимо решение, удовлетворяющее следующим критериям:

Решение

Мы разработали npm-пакет, для добавления таймаутов к gRPC-запросам. Таймауты сервисов будут распространяться дальше по цепочке и как только любой из них истечёт, будет возвращён ответ “4 DEADLINE_EXCEEDED”. Запросы с заведомо истекшим таймаутом не обрабатываются сервером и не отправляются клиентами. Таймауты можно настраивать как в разрезе конкретных методов, так и для целых клиентов/сервисов. Помимо таймаутов можно настроить минимальное время, нужное сервису чтобы ответить. Если время до истечения таймаута будет меньше, чем минимальное время ответа сервиса — таймаут будет расценен как истёкший. Подключается пакет в пару строчек кода и имеет дефолтную конфигурацию — таймауты в 10 секунд и минимальное время ответа сервисов — 0 мс.

Результат

Пакет был успешно применён в продакшене и решил поставленную проблему. Найти пакет можно на странице в GitHub.

Распространение запроса по цепочке микросервисов: Без таймаутов, с таймаутом в 5 секунд для каждого сервиса и с таймаутом в 5 секунд при использовании нашего решения.