На каком транспортном протоколе работает gRPC
Что проверяют
Отвечаете ли вы «HTTP/2» на автомате или понимаете, что это уровень приложения поверх обычного TCP, и что из этого следует. Следом спрашивают, почему gRPC не вызвать из браузера напрямую и что ломается за балансировщиком четвёртого уровня.
Как отвечать
Транспорт это TCP, поверх него HTTP/2 как протокол кадрирования, обычно с TLS и согласованием h2 через ALPN. Во внутреннем периметре допустим h2c без шифрования.
- один вызов равен одному потоку HTTP/2: мультиплексирование в одном соединении, без очереди HTTP/1.1 и без пула соединений;
- вызов ложится на HTTP-семантику: метод
POST, путь/пакет.Сервис/Метод, заголовокcontent-type: application/grpc+proto, тело это сообщения с пятибайтовым префиксом (флаг сжатия и длина), результат в трейлерахgrpc-statusиgrpc-message; - потоки и трейлеры дают четыре режима вызова: unary, серверный стрим, клиентский стрим и двунаправленный;
- управление потоком: окна HTTP/2 на поток и на соединение, стартовое окно 64 КБ, дальше реализации расширяют его динамически или поднимают явно (
grpc.WithInitialWindowSizeв Go).
Отсюда ответ про браузер: fetch не даёт доступа к трейлерам и сырым кадрам, поэтому нужен gRPC-Web с прокси (Envoy) либо протокол Connect.
Соединение долгоживущее, поэтому балансировщик четвёртого уровня прибивает клиента к одному поду навсегда: спасает клиентская балансировка с round_robin, прокси седьмого уровня либо MaxConnectionAge в keepalive.ServerParameters, чтобы сервер сам слал GOAWAY. Слишком частые keepalive-пинги с клиента получают в ответ ENHANCE_YOUR_CALM. Блокировка головы очереди на уровне TCP остаётся, HTTP/2 её не лечит, это умеет только QUIC.
В Go добавьте практику: grpc.NewClient вместо устаревшего grpc.Dial, insecure.NewCredentials() только для локального стенда, дедлайн на каждый вызов.
Где спотыкаются
Говорят «HTTP/2» и замолкают. Уточнение про транспортный уровень ставит в тупик, хотя ответ простой: TCP.
Уверены, что gRPC вызывается из браузера напрямую, и путают его с gRPC-Web.
Ставят gRPC за обычный TCP-балансировщик и потом ищут, почему нагрузка легла на один инстанс из десяти.