Данный документ служит подробным описанием для реализации gRPC, передаваемой через обрамление HTTP2. Документ предполагает знакомство с спецификацией HTTP2.
Правила производства используют синтаксис ABNF.
Вот общий последовательный поток атомов сообщений в потоке запросов и ответов gRPC:
Если Timeout не указан, сервер должен предполагать бесконечное время ожидания. Реализации клиента могут отправлять по умолчанию минимальное время ожидания, основанное на требованиях их развертывания.
Если Content-Type не начинается с "application/grpc", gRPC-серверы ДОЛЖНЫ отвечать статусом HTTP 415 (Unsupported Media Type). Это предотвратит другие клиенты HTTP/2 от интерпретации ответа ошибки gRPC, который использует статус 200 (OK), как успешного.
Custom-Metadata представляет собой произвольное множество пар ключ-значение, определённое уровнем приложения. Заголовки, начинающиеся с "grpc-", но не перечисленные здесь, зарезервированы для будущего использования gRPC и не должны использоваться приложениями как Custom-Metadata.Обратите внимание, что HTTP/2 не позволяет произвольные последовательности октетов для значений заголовков, поэтому двоичные заголовки должны быть закодированы с помощью Base64 в соответствии с https://tools.ietf.org/html/rfc4648#section-4. Реализации ДОЛЖНЫ принимать закодированные и не закодированные значения и должны отправлять не закодированные значения. Приложения определяют двоичные заголовки тем, что их имена заканчиваются на "-bin". Библиотеки выполнения используют этот суффикс для обнаружения двоичных заголовков и правильного применения кодирования и декодирования Base64 при отправке и получении заголовков.Порядок заголовков Custom-Metadata не гарантируется, за исключением значений с дублирующими заголовками. Дублирующие заголовки могут иметь свои значения объединенными запятой (",") как разделитель и рассматриваться как семантически эквивалентные. Реализации должны разделять Binary-Headers на запятые перед декодированием закодированных значений Base64. Значение ASCII не должно содержать начальных или конечных пробелов. Если такие пробелы присутствуют, их можно удалить. Определенный диапазон символов для Значения ASCII строже, чем в HTTP. Реализации не должны выдавать ошибку при получении недопустимого Значения ASCII, которое является допустимым значением поля в HTTP, но точное поведение не строго определено: они могут игнорировать это значение или принимать его. Если значение принимается, необходимо убедиться, что приложение имеет разрешение повторно отобразить это значение как метаданные. Например, если метаданные предоставляются приложению в виде списка в запросе, приложение не должно вызывать ошибку, предоставив тот же список как метаданные в ответе. Серверы могут ограничивать размер Request-Headers, с рекомендацией по умолчанию 8 КБ.Реализации поощряются вычислять общий размер заголовков, как это делается в HTTP/2 для SETTINGS_MAX_HEADER_LIST_SIZE
: сумма всех заголовков, для каждого поля сумма несжатых длины имени и значения заголовка плюс 32, с длиной бинарных значений после Base64.Повторяющаяся последовательность элементов Length-Prefixed-Message передается в DATA-фреймах.
Значение Compressed-Flag равное 1 указывает на то, что последовательность бинарных октетов Message сжата с использованием механизма, объявленного заголовком Message-Encoding. Значение 0 указывает на то, что сжатие Message не применялось. Контексты сжатия не сохраняются между границами сообщений, реализации должны создавать новый контекст для каждого сообщения в потоке. Если заголовок Message-Encoding отсутствует, то Compressed-Flag должен быть равен 0.
Для запросов EOS (end-of-stream) указывается наличием флага END_STREAM в последнем полученных DATA-фрейме. В ситуациях, когда поток Request должен быть закрыт, но больше данных отправлено не будет, реализации должны отправить пустой DATA-фрейм с этим флагом установленным.
Заголовки-ответа и Трейлеры-только отправляются в отдельных блоках HTTP2 HEADERS. Большинство ответов должны содержать как заголовки, так и трейлеры, но Трейлеры-только допускаются для вызовов, которые приводят к немедленной ошибке. Статус должен отправляться в Трейлерах, даже если код состояния является OK. Для завершения потока используется флаг END_STREAM в последующем получаемом фрейме HEADERS, который содержит Трейлеры.Реализации должны ожидать, что в ответах могут поступать HTTP-статусы, отличные от 200, а также различные типы содержимого, отличные от GRPC, а также отсутствие Status и Status-Message. Реализации должны синтезировать Status и Status-Message для передачи на уровень приложения в случае возникновения таких ситуаций.
Клиенты могут ограничивать размер Response-Headers, Trailers и Trailers-Only с рекомендацией по умолчанию в 8 КБ для каждого.
Часть значения Status представляет собой десятичное число, закодированное в ASCII без ведущих нулей.
Часть значения Status-Message представляет собой концептуально Unicode-строку, описывающую ошибку, физически закодированную в UTF-8, за которым следует percent-encoding. Percent-encoding определен в RFC 3986 §2.1, хотя форма, используемая здесь, имеет другие ограниченные символы. При декодировании недействительных значений реализации не должны генерировать ошибки или игнорировать сообщение. В худшем случае реализация может прервать декодирование сообщения статуса, так что пользователь получит сырую percent-закодированную форму. В качестве альтернативы реализация может декодировать корректные части, оставляя поврежденные %-закодированные части без изменений или заменяя их символом замены (например, '?' или Unicode-символом замены).#### Пример
Пример одиночного вызова, показывающий последовательность фреймов HTTP2
Запрос
HEADERS (flags = END_HEADERS)
:method = POST
:scheme = http
:path = /google.pubsub.v2.PublisherService/CreateTopic
:authority = pubsub.googleapis.com
grpc-timeout = 1S
content-type = application/grpc+proto
grpc-encoding = gzip
authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v
DATA (flags = END_STREAM)
<Length-Prefixed Message>
Ответ
HEADERS (flags = END_HEADERS)
:status = 200
grpc-encoding = gzip
content-type = application/grpc+proto
DATA
<Length-Prefixed Message>
HEADERS (flags = END_STREAM, END_HEADERS)
grpc-status = 0 # OK
trace-proto-bin = jher831yy13JHy3hc
Хотя протокол не требует функционирования user-agent, рекомендуется, чтобы клиенты предоставляли структурированную строку user-agent, которая предоставляет базовое описание вызывающей библиотеки, версии и платформы для облегчения диагностики проблем в разнородных окружениях. Рекомендуемая структура для библиотекарей:
User-Agent → "grpc-" Language ?("-" Variant) "/" Version ?( " (" *(AdditionalProperty ";") ")" )
Пример:
grpc-java/1.2.3
grpc-ruby/1.2.3
grpc-ruby-jruby/1.3.4
grpc-java-android/0.9.1 (gingerbread/1.2.4; nexus5; tmobile)
Если явно не определено, gRPC вызовы не считаются идемпотентными. В частности:
Все GRPC вызовы должны указывать внутренний ID. Мы будем использовать HTTP2 stream-ids как идентификаторы вызовов в этой схеме. ЗАМЕЧАНИЕ: Эти ID являются контекстными для открытой HTTP2 сессии и не будут уникальными в процессе, обрабатывающем более одной HTTP2 сессии, и не могут быть использованы как GUID.
Границы фреймов DATA не имеют отношения к границам Length-Prefixed-Message и реализации не должны делать предположений о их выравнивании.
Когда приложение или среда выполнения сталкиваются с ошибкой во время RPC, Status и Status-Message передаются в Trailers.
В некоторых случаях возможно, что форматирование потока сообщений стало повреждённым, и среда выполнения RPC выберет использовать фрейм RST_STREAM для указания этого состояния своему сопровождающему. Реализации среды выполнения RPC должны интерпретировать RST_STREAM как полное немедленное закрытие потока и должны передать ошибку в приложение-посыльное.Следующее отображение кодов ошибок RST_STREAM на коды ошибок GRPC применяется.
HTTP2 Код | GRPC Код |
---|---|
NO_ERROR(0) | INTERNAL - Ясное GRPC состояние OK должно было быть отправлено, но это может использоваться для агрессивного lameducking в некоторых сценариях. |
PROTOCOL_ERROR(1) | INTERNAL |
INTERNAL_ERROR(2) | INTERNAL |
FLOW_CONTROL_ERROR(3) | INTERNAL |
SETTINGS_TIMEOUT(4) | INTERNAL |
STREAM_CLOSED | Нет соответствия, так как открытого потока для распространения нет. Реализации должны регистрировать. |
FRAME_SIZE_ERROR | INTERNAL |
REFUSED_STREAM | UNAVAILABLE - Указывает, что обработка не происходила, и запрос может быть повторен, возможно, в другом месте. |
CANCEL(8) | Мапится на отмену вызова, когда отправлено клиентом. Мапится на CANCELLED, когда отправлено сервером. Обратите внимание, что серверы должны использовать этот механизм только в том случае, если им нужно отменить вызов, но последовательность байтов содержимого не завершена. |
COMPRESSION_ERROR | INTERNAL |
CONNECT_ERROR | INTERNAL |
ENHANCE_YOUR_CALM | RESOURCE_EXHAUSTED ... с дополнительными деталями ошибки, предоставленными средой выполнения, чтобы указать, что исчерпанный ресурс - это пропускная способность. |
INADEQUATE_SECURITY | PERMISSION_DENIED … с дополнительными деталями, указывающими, что разрешение было отказано, так как протокол недостаточно безопасен для вызова. |
Отправляется сервером клиенту для указания, что сервер больше не будет принимать новые потоки на связанных соединениях. Этот фрейм включает идентификатор последнего успешно принятого потока сервером. Клиенты должны рассматривать любой поток, инициированный после последнего успешно принятого потока, как недоступный и повторно пытаться вызов в другом месте. Клиенты могут продолжать работать с уже принятыми потоками до тех пор, пока они не завершатся или соединение не будет завершено.
Серверы должны отправлять фрейм GOAWAY перед завершением соединения для надежного уведомления клиентов о том, какие работы были приняты сервером и выполняются.###### PING Frame Оба клиента и серверы могут отправлять PING frame, на который соответствующий узел должен ответить, точно повторяя то, что получил. Это используется для проверки, что соединение все еще активно, а также для оценки задержки от конца до конца. Если сервер, инициированный PING, не получит ответа в течение ожидаемого срока выполнения, все ожидающие вызовы на сервере будут закрыты со статусом CANCELLED. Устаревший клиент, инициированный PING, приведет к закрытию всех вызовов со статусом UNAVAILABLE. Обратите внимание, что частота PING зависит от сетевой среды, реализации могут корректировать частоту PING в зависимости от сетевых и прикладных требований.###### Сбой соединения Если обнаруживается сбой соединения на клиенте, все вызовы будут закрыты со статусом UNAVAILABLE. Для серверов открытые вызовы будут закрыты со статусом CANCELLED.
Интерфейсы служб, объявленные в protobuf, легко отображаются на GRPC с помощью расширений генерации кода для protoc. Ниже приведено определение отображения, которое следует использовать.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )