HTTP 200 в журнале прокси не гарантирует успешный gRPC-вызов. Проверьте итоговый статус у gRPC-клиента: код OK (0) означает успешное завершение RPC, остальные коды требуют разбора.
Сначала сопоставьте один проблемный вызов в клиенте, прокси и приложении, затем повторите безопасный запрос тем же методом. Так можно отличить отказ приложения от потери завершающих метаданных или тайм-аута по пути.
Почему 200 и ошибка не противоречат друг другу
В обычном gRPC поверх HTTP/2 есть два результата: HTTP-статус и статус самого RPC. Согласно описанию протокола gRPC, итоговый grpc-status передаётся в trailers — метаданных, завершающих поток; при немедленной ошибке возможен ответ только с метаданными, без сообщения.
Поэтому строка 200 в access log описывает лишь часть обмена. Для потокового метода даже несколько полученных сообщений ещё не означают, что весь вызов завершился успешно. Если клиент не получил корректного завершения, отсутствие grpc-status нельзя считать нулевым кодом.
Это руководство относится к обычному gRPC поверх HTTP/2. У gRPC-Web и JSON-шлюза способ передачи результата другой: сначала уточните, какой протокол использует клиент.
1. Соберите результат одного вызова
Выберите конкретный случай и запишите:
- время с часовым поясом, имя сервиса и метода;
- адрес назначения, версию клиента и приложения;
- HTTP-статус, если он доступен, итоговый gRPC-код и текст ошибки;
- установленный deadline — срок ожидания вызова — и фактическую длительность;
- идентификатор трассировки и число попыток, если они фиксируются.
Не объединяйте HTTP 200 одной попытки и ошибку другой. Повтор внутри клиентской библиотеки может скрыть первый отказ, а одинаковый метод — попасть на разные узлы.
Сохраните диагностические данные без токенов, персональных данных и содержимого рабочих сообщений. Сам текст ошибки тоже может содержать чувствительные сведения.
2. Повторите безопасный RPC полноценным клиентом
Открытие адреса в браузере или curl -I не воспроизводит gRPC-вызов. Используйте штатный клиент либо grpcurl: инструмент вызывает RPC и показывает ответ и ошибку.
Пример для тестового сервиса с включённой server reflection, которая позволяет получить описание методов:
grpcurl -v -d '{}' api.example.com:443 example.v1.Diagnostics/Check
Адрес, метод и пустое сообщение здесь условные. Замените их на разрешённый метод чтения или диагностики с известным ожидаемым результатом; команда сама по себе не делает произвольный метод безопасным.
Если reflection отключена, используйте согласованный .proto или protoset, как описано в документации grpcurl. Отказ reflection ещё не доказывает отказ нужного RPC. Не отключайте проверку TLS ради успешного теста и не переносите рабочие секреты в команду или отчёт.
Сравните результат штатного клиента и теста при сопоставимых параметрах. Если отличается только один клиент, проверьте его deadline, перехватчики и обработку завершения потока до изменения серверной конфигурации.
3. Выберите ветку по итоговому коду
Справочник gRPC задаёт смысл кодов. Практический порядок проверки такой:
| Результат | Что проверить сначала | | --- | --- | | UNAUTHENTICATED (16), PERMISSION_DENIED (7) | Личность клиента, передачу авторизационных метаданных, права на метод | | INVALID_ARGUMENT (3), FAILED_PRECONDITION (9) | Соответствие сообщения контракту и состояние объекта | | DEADLINE_EXCEEDED (4) | Бюджет времени клиента, очередь и длительность работы сервера | | UNAVAILABLE (14) | Доступность нужного узла, события релиза и сбои соединения | | INTERNAL (13), UNKNOWN (2) | Журнал приложения и клиента по тому же идентификатору |
Код задаёт направление, но не называет виновный компонент. Например, недоступность сервиса не доказывает, что весь хостинг упал.
После тайм-аута операции записи сначала выясните, выполнена ли она. Не включайте безусловные повторы платежа или создания заказа: безопасный повтор требует предусмотренной защиты от дублей.
4. Если итоговых метаданных нет, сравните участки пути
Нарисуйте цепочку клиент → балансировщик → прокси → gRPC-сервер. Для каждого узла проверьте поддержку gRPC, протокол до следующего узла, ограничения времени и запись завершения вызова.
В разрешённом тестовом контуре сравните один безопасный RPC через внешний адрес и напрямую к сервису. Сохраните сопоставимые TLS-настройки, имя назначения, метод и параметры; иначе тест будет проверять другую конфигурацию.
Если напрямую вызов завершается, а через прокси обрывается, изучайте этот участок: тайм-аут, сброс потока, передачу trailers. При связи с выкладкой пригодится отдельная проверка завершения HTTP/2-запросов при релизе.
Как подтвердить исправление и продолжить контроль
Повторите исходный безопасный сценарий: клиент должен получить ожидаемые данные и корректное завершение RPC. Отдельно проверьте контролируемую ошибку: она должна оставаться видимой как ошибка, даже если HTTP-журнал показывает 200.
Для регулярного контроля разделите доступность публичной HTTP-точки и результат конкретного RPC. Web-Puls можно использовать для HTTP-проверки выбранного URL; чтение gRPC trailers и выполнение RPC такая проверка не подтверждает. Общие критерии выбора точки разобраны в руководстве по мониторингу API.
Если границу сбоя определить не удалось, отправьте заявку на диагностику: укажите адрес сервиса, время, метод, итоговый код и обезличенные результаты сравнения. Пароли, токены и рабочие сообщения прикладывать не нужно.