Triple 协议设计理念与规范 您所在的位置:网站首页 dubbo扩展机制 Triple 协议设计理念与规范

Triple 协议设计理念与规范

#Triple 协议设计理念与规范 | 来源: 网络整理| 查看: 265

Triple 协议设计理念与规范Triple 协议规范1 协议设计理念

Triple 协议的设计参考了 gRPC、gRPC-Web、通用 HTTP 等多种协议模式,吸取每个协议各自的特性和优点,最终设计成为一个易于浏览器访问、完全兼容 gRPC 且支持 Streaming 通信的协议,Triple 支持同时运行在 HTTP/1、HTTP/2 协议之上。

Triple 协议的设计目标如下:

Triple 设计为对人类、开发调试友好的一款基于 HTTP 的协议,尤其是对 unary 类型的 RPC 请求。完全兼容基于 HTTP/2 的 gRPC 协议,因此 Dubbo Triple 协议实现可以 100% 与 gRPC 体系互调互通。仅依赖标准的、被广泛使用的 HTTP 特性,以便在实现层面可以直接依赖官方的标准 HTTP 网络库。

当与 Protocol Buffers 一起使用时(即使用 IDL 定义服务),Triple 协议可支持 unary、client-streaming、server-streaming 和 bi-streaming RPC 通信模式,支持二进制 Protobuf、JSON 两种数据格式 payload。 Triple 实现并不绑定 Protocol Buffers,比如你可以使用 Java 接口定义服务,Triple 协议有对这种模式的扩展 Content-type 支持。

2 示例2.1 Unary 请求

以 HTTP/1 请求为例,目前 HTTP/1 协议仅支持 Unary RPC,支持使用 application/proto 和 application/json 编码类型,使用方式与 REST 风格请求保持一致,同时响应也包含常规的 HTTP 响应编码(如 200 OK)。

> POST /org.apache.dubbo.demo.GreetService/Greet HTTP/1.1 > Host: 127.0.0.1:30551 > Content-Type: application/json > > ["Dubbo"] < HTTP/1.1 200 OK < Content-Type: application/json < < {"greeting": "Hello, Dubbo!"}

一个包含指定超时时间的调用请求。

> POST /org.apache.dubbo.demo.GreetService/Greet HTTP/1.1 > Host: 127.0.0.1:30551 > Content-Type: application/json > Rest-service-timeout: 5000 > > ["Dubbo"] < HTTP/1.1 200 OK < Content-Type: application/json < < {"greeting": "Hello, Buf!"}

目前仅支持 POST 请求类型,我们将考虑在未来支持 GET 请求类型,GET 请求可能适用于具有幂等属性的一些服务调用。

2.2 Streaming 调用请求

Triple 仅支持在 HTTP/2 上支持 Streaming RPC。并且为了与 gRPC 协议保持兼容,Triple 在 HTTP/2 协议实现上(包含 Streaming RPC)保持与标准 gRPC 协议完全一致。

Request

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)

Response

HEADERS (flags = END_HEADERS) :status = 200 grpc-encoding = gzip content-type = application/grpc+proto DATA HEADERS (flags = END_STREAM, END_HEADERS) grpc-status = 0 # OK trace-proto-bin = jher831yy13JHy3hc 3 规范详情

Triple 协议支持同时运行在 HTTP/1 和 HTTP/2 协议之上,其包含以下两部分内容:

一套自定义的精简 HTTP RPC 子协议,支持 HTTP/1 和 HTTP/2 作为传输层实现,仅支持 Request-Response 类型的 Unary RPC。一套基于 gRPC 协议的扩展子协议(仍保持和 gRPC 的 100% 兼容),仅支持 HTTP/2 实现,支持 Streaming RPC。3.1 Triple 之 HTTP RPC 协议

大部分的 RPC 调用都是 unary (request-response) 模式的。Triple HTTP RPC 协议 unary 模式能很好的满足后端服务间的数据传输需求,同时可以让浏览器、cURL 以及其他一些 HTTP 工具更容易的访问后端服务,即使用标准的 HTTP 协议发起调用即可。

Triple HTTP RPC 同时支持 HTTP/1、HTTP/2 作为底层传输层协议,在实现上对应支持的 content-type 类型为 application/json、application/proto

3.1.1 请求 RequestRequest → Request-Headers Bare-MessageRequest-Headers → Call-Specification *Leading-MetadataCall-Specification → Schema Http-Method Path Http-Host Content-Type TRI-Service-Timeout TRI-Service-Version TRI-Service-Group Content-Encoding Accept-Encoding Accept Content-LengthScheme → “http” / “https”Http-Method → POSTPath → /Service-Name/Method-Name; case-sensitiveService-Name → service interface full classnameMethod-Name → service interface declared method`s nameHttp-Host → Target-IP:Target-PortTarget-IP → target server ip or domainTarget-Port → target server process portContent-Type → “Content-Type: ” “application/” Message-CodecMessage-Codec → (“json” / {custom})TRI-Protocol-Version → “tri-protocol-version” “1”TRI-Service-Timeout → “tri-service-timeout: ” Timeout-MillisecondsTimeout-Milliseconds → positive integerTRI-Service-Version → “tri-unary-service-version: ” VersionVersion → dubbo service versionTRI-Service-Group → “tri-service-group: " GroupGroup → dubbo service groupContent-Encoding → “content-encoding” Content-CodingContent-Coding → “identity” / “gzip” / “br” / “zstd” / {custom}Accept-Encoding → “accept-encoding” Content-Coding *(”," [" “] Content-Coding) ; subset of HTTP quality value syntaxContent-Length → length of the encoded payloadLeading-Metadata → Custom-MetadataCustom-Metadata → ASCII-Metadata / Binary-MetadataASCII-Metadata → Header-Name ASCII-ValueBinary-Metadata → {Header-Name “-bin”} {base64-encoded value}Header-Name → 1*( %x30-39 / %x61-7A / “_” / “-” / “.”) ; 0-9 a-z _ - .ASCII-Value → 1*( %x20-%x7E ) ; space & printable ASCIIBare-Message → data that encoded by json or custom and Content-Encoding

Triple 协议请求的仅支持 POST 请求,请求 path 为 interfaceName/methodName,为了实现调用超时机制,需要添加 tri-service-timeout (单位 ms),

Dubbo 框架支持基于 分组(group) 和 版本(version) 的服务隔离机制,因此 Triple 协议中引入了 tri-service-group、tri-service-version 支持。

Request-Headers 以标准的 HTTP header 的形式发送,如果收到的 headers 数量过多,server 可返回相应错误信息。

TRI-Protocol-Version 头用来区分具有相同 Content-Type 的 triple 协议请求和其他协议请求,因为 application/json 格式的 Content-Type 非常普遍。所有的 Dubbo 原生客户端实现都应该在请求中携带 TRI-Protocol-Version,Dubbo 服务端或代理可以选择拒绝没有 TRI-Protocol-Version 的请求并返回 Http-Status 400 错误。

如果 Server 不支持 Message-Codec 指定的编码格式,则必须返回标准 HTTP 415 编码表明 Unsupported Media Type 异常。

Bare-Message 即请求 payload 的编码格式取决于 Message-Codec 设置:

Message-Codec: json 的场景下,payload 采用有序的数组编码形式,即将 rpc 方法的参数按顺序组装进 Array 后进行 json 序列化,方法参数的位置与数组下标保持一致,当 Triple server 接收到请求体时,根据每个参数的类型进行反序列化成对应的参数数组。对于使用 Protocol Buffer 的情形,payload 则是只有一个 json 对象的数组。Message-Codec: proto 的场景下,Protobuf 生成的 Request 类包含了编码格式,因此将直接使用 Request 对象中的内置编码方式。Message-Codec 支持更多自定义扩展值,请确保框架实现遵循相应的编码与解码约定。

如果 Content-Encoding 指定了相应值,则 payload 是被压缩过的,应该首先进行解压缩后再解析编码数据,Bare-Message 将作为 HTTP Body 在链路上传输。

Request 报文示例请求行POST /org.apache.dubbo.demo.GreetService/greeting HTTP/1.1请求头Host: 127.0.0.1:30551Content-Type: application/jsonAccept: application/jsonContent-Length: 11Accept-Encoding: compress, gziptri-service-version: 1.0.0tri-service-group: dubbotri-service-timeout: 3000请求体[{“world”}]POST /org.apache.dubbo.demo.GreetService/Greet HTTP/1.1 Host: 127.0.0.1:30551 Content-Type: application/json Accept: application/json Content-Length: 11 Accept-Encoding: compress, gzip tri-service-version: 1.0.0 tri-service-group: dubbo tri-service-timeout: 3000 [{"world"}] 3.1.2 响应 ResponseResponse → Response-Headers *Bare-MessageResponse-Headers → HTTP-Status Content-Type [Content-Encoding] [Accept-Encoding] *Leading-Metadata *Prefixed-Trailing-MetadataHTTP-Status → 200 /{error code translated to HTTP}Bare-Message → data that encoded by Content-Type and Content-Encoding

对于成功 Response 响应 HTTP-Status 是 200,在这种场景下,响应体的 Content-Type 将保持和请求体的 Content-Type 保持一致。Bare-Message 就是 RPC 响应的 Payload,以 Content-Type 指定的方式进行编码并且以 Content-Encoding 来压缩(如果指定了 Content-Encoding 的话)。Bare-Message 作为 HTTP response body 发送。

异常 Response 响应的 HTTP-Status 是 non-200,并且都是标准的 HTTP status code,在这个场景下,Content-Type 必须是 “application/json”。Bare-Message 可以是空的,如果 Bare-Message 有值的话则是一个标准 JSON 格式数据,如果 Content-Encoding 有指定的话则是一个压缩过的数据,Bare-Message 作为标准的 HTTP response body 发送回调用方。客户端可以根据以下表格,查询 HTTP-Status 与 RPC status 之间的映射关系,以了解具体的 RPC 错误情况。

Response 报文格式

** 成功响应 **

HTTP/1.1 200 OK Content-Type: application/json Content-Length: 11 hello world

** 失败响应 **

HTTP/1.1 400 Bad Request Content-Type: application/json Content-Length: 46 {"status":20,"message":"request format error"} 3.1.3 Error Codes

Dubbo 的错误码参考

status http-status message 20 200 ok 25 400 serialization error 30 408 client side timeout 31 408 server side timeout 35 500 channel inactive, directly return the unfinished requests 40 400 request format error 50 500 response format error 60 404 service not found. 70 500 service error 80 500 internal server error 90 500 internal client error

Connect 的 HTTP to Error Code 参考

HTTP StatusInferred Code400 Bad Requestinvalid_argument401 Unauthorizedunauthenticated403 Forbiddenpermission_denied404 Not Foundunimplemented408 Request Timeoutdeadline_exceeded409 Conflictaborted412 Precondition Failedfailed_precondition413 Payload Too Largeresource_exhausted415 Unsupported Media Typeinternal429 Too Many Requestsunavailable431 Request Header Fields Too Largeresource_exhausted502 Bad Gatewayunavailable503 Service Unavailableunavailable504 Gateway Timeoutunavailableall othersunknown3.2 Triple 之扩展版 gRPC 协议

Triple 协议的 Streaming 请求处理完全遵循 gRPC 协议规范,且仅支持 HTTP/2 作为传输层协议。

Triple 支持的 content-type 类型为标准的 gRPC 类型,包括 application/grpc、application/grpc+proto、application/grpc+json,除此之外,Triple 在实现上还扩展了 application/triple+wrapper 编码格式。

3.2.1 Outline

The following is the general sequence of message atoms in a GRPC request & response message stream

Request → Request-Headers *Length-Prefixed-Message EOSResponse → (Response-Headers *Length-Prefixed-Message Trailers) / Trailers-Only3.2.2 RequestsRequest → Request-Headers *Length-Prefixed-Message EOS

Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames.

Request-Headers → Call-Definition *Custom-MetadataCall-Definition → Method Scheme Path TE [Authority] [Timeout] Content-Type [Message-Type] [Message-Encoding] [Message-Accept-Encoding] [User-Agent] Service-Version Service-Group Tracing-ID Tracing-Span-ID Cluster-InfoMethod → “:method POST”Scheme → “:scheme " (“http” / “https”)Path → “:path” “/” Service-Name “/” {method name} # But see note below.Service-Name → {IDL-specific service name}Authority → “:authority” {virtual host name of authority}TE → “te” “trailers” # Used to detect incompatible proxiesTimeout → “grpc-timeout” TimeoutValue TimeoutUnitTimeoutValue → {positive integer as ASCII string of at most 8 digits}TimeoutUnit → Hour / Minute / Second / Millisecond / Microsecond / NanosecondHour → “H”Minute → “M”Second → “S”Millisecond → “m”Microsecond → “u”Nanosecond → “n”Content-Type → “content-type” “application/grpc” [("+proto” / “+json” / {custom})]Content-Coding → “identity” / “gzip” / “deflate” / “snappy” / {custom}Message-Encoding → “grpc-encoding” Content-CodingMessage-Accept-Encoding → “grpc-accept-encoding” Content-Coding *("," Content-Coding)User-Agent → “user-agent” {structured user-agent string}Message-Type → “grpc-message-type” {type name for message schema}Custom-Metadata → Binary-Header / ASCII-HeaderBinary-Header → {Header-Name “-bin” } {base64 encoded value}ASCII-Header → Header-Name ASCII-ValueHeader-Name → 1*( %x30-39 / %x61-7A / “_” / “-” / “.”) ; 0-9 a-z _ - .ASCII-Value → 1*( %x20-%x7E ) ; space and printable ASCIIService-Version → “tri-service-version” {Dubbo service version}Service-Group → “tri-service-group” {Dubbo service group}Tracing-ID → “tri-trace-traceid” {tracing id}Tracing-RPC-ID → “tri-trace-rpcid” {_span id _}Cluster-Info → “tri-unit-info” {cluster infomation}3.2.3 ResponsesResponse → (Response-Headers *Length-Prefixed-Message Trailers) / Trailers-OnlyResponse-Headers → HTTP-Status [Message-Encoding] [Message-Accept-Encoding] Content-Type *Custom-MetadataTrailers-Only → HTTP-Status Content-Type TrailersTrailers → Status [Status-Message] *Custom-MetadataHTTP-Status → “:status 200”Status → “grpc-status” 1*DIGIT ; 0-9Status-Message → “grpc-message” Percent-EncodedPercent-Encoded → 1*(Percent-Byte-Unencoded / Percent-Byte-Encoded)Percent-Byte-Unencoded → 1*( %x20-%x24 / %x26-%x7E ) ; space and VCHAR, except %Percent-Byte-Encoded → “%” 2HEXDIGIT ; 0-9 A-F

以上即为 Triple 扩展版本的 gRPC 协议,更多详细规范说明请参照 gRPC 协议规范。

反馈

此页是否对您有帮助?

最后修改 July 5, 2023: update triple spec again due to github synchronization delay (#2765) (753bfbeafb)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有