gRPC не делает сеть надёжной. Нужны дедлайны, ограниченные ретраи и обработка перегрузки.

Когда повторять

Unavailable может быть временным сбоем. DeadlineExceeded не является приглашением повторить немедленно: возможно, операция уже выполнена.

Повторяют только идемпотентные операции или запросы с ключом идемпотентности. Повтор с экспоненциальным backoff и jitter, ограниченный общим бюджетом.

FailedPrecondition, InvalidArgument и большинство Internal не повторяют: причина не исчезнет сама.

Неизвестный исход

После обрыва нельзя утверждать, что операции не было. Платёжный вызов сначала проверяет статус по idempotency key, а не списывает снова.

обрыв связи проверить статус получить исход решить о повторе

После обрыва исход платежа неизвестен. Сначала ищут результат по ключу идемпотентности, а не списывают повторно.

Если сервер не сохранил ключ, восстановление становится риском дубля. Поэтому идемпотентность начинается с уникального ключа и хранения результата.

Backpressure

Клиент ограничивает параллелизм и ожидание места. Сервер отвечает ResourceExhausted при перегрузке, а не накапливает бесконечные вызовы.

В потоке отправка тоже ограничена: медленный получатель не должен увеличивать очередь без границ. Выбирают блокировку, отказ или пропуск по типу данных.

Бюджет повтора

Backoff ограничивает и задержку, и число попыток, и общий дедлайн. Например, начинают со 100 мс, удваивают задержку до секунды и добавляют небольшой случайный jitter, чтобы ожидающие клиенты не повторили запрос одновременно. После трёх попыток или исчерпания общего контекста прекращают.

DeadlineExceeded означает неизвестный исход, а не обязательный отказ. Поэтому следующий вызов выполняют только после проверки статуса. Если его невозможно проверить, безопаснее вернуть неопределённость наверх, чем списать деньги повторно.

Для стримов повтор создаёт новый вызов, а не продолжение с середины. Чтобы не получить дубли событий, передают последний подтверждённый offset или event ID.

Коротко

  • Повторяют временные ошибки и только идемпотентные операции.
  • После таймаута сначала проверяют статус.
  • ResourceExhausted честно сообщает о перегрузке.
  • Backpressure ограничивает и вызовы, и потоковые сообщения.