gRPC не делает сеть надёжной. Нужны дедлайны, ограниченные ретраи и обработка перегрузки.
Когда повторять
Unavailable может быть временным сбоем. DeadlineExceeded не является приглашением повторить немедленно: возможно, операция уже выполнена.
Повторяют только идемпотентные операции или запросы с ключом идемпотентности. Повтор с экспоненциальным backoff и jitter, ограниченный общим бюджетом.
FailedPrecondition, InvalidArgument и большинство Internal не повторяют: причина не исчезнет сама.
Неизвестный исход
После обрыва нельзя утверждать, что операции не было. Платёжный вызов сначала проверяет статус по idempotency key, а не списывает снова.
После обрыва исход платежа неизвестен. Сначала ищут результат по ключу идемпотентности, а не списывают повторно.
Если сервер не сохранил ключ, восстановление становится риском дубля. Поэтому идемпотентность начинается с уникального ключа и хранения результата.
Backpressure
Клиент ограничивает параллелизм и ожидание места. Сервер отвечает ResourceExhausted при перегрузке, а не накапливает бесконечные вызовы.
В потоке отправка тоже ограничена: медленный получатель не должен увеличивать очередь без границ. Выбирают блокировку, отказ или пропуск по типу данных.
Бюджет повтора
Backoff ограничивает и задержку, и число попыток, и общий дедлайн. Например, начинают со 100 мс, удваивают задержку до секунды и добавляют небольшой случайный jitter, чтобы ожидающие клиенты не повторили запрос одновременно. После трёх попыток или исчерпания общего контекста прекращают.
DeadlineExceeded означает неизвестный исход, а не обязательный отказ. Поэтому следующий вызов выполняют только после проверки статуса. Если его невозможно проверить, безопаснее вернуть неопределённость наверх, чем списать деньги повторно.
Для стримов повтор создаёт новый вызов, а не продолжение с середины. Чтобы не получить дубли событий, передают последний подтверждённый offset или event ID.
Коротко
- Повторяют временные ошибки и только идемпотентные операции.
- После таймаута сначала проверяют статус.
ResourceExhaustedчестно сообщает о перегрузке.- Backpressure ограничивает и вызовы, и потоковые сообщения.