注意:此文档描述的内容正在建设中或处于功能早期阶段,请持续关注文档更新!
Triple 协议的设计参考了 gRPC、gRPC-Web、通用 HTTP 等多种协议模式,吸取每个协议各自的特性和优点,最终设计成为一个易于浏览器访问、完全兼容 gRPC 且支持 Streaming 通信的协议,Triple 支持同时运行在 HTTP/1、HTTP/2 协议之上。
Triple 协议的设计目标如下:
当与 Protocol Buffers 一起使用时(即使用 IDL 定义服务),Triple 协议可支持 unary、client-streaming、server-streaming 和 bi-streaming RPC 通信模式,支持二进制 Protobuf、JSON 两种数据格式 payload。 Triple 实现并不绑定 Protocol Buffers,比如你可以使用 Java 接口定义服务,Triple 协议有对这种模式的扩展 Content-type 支持。
以 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 请求可能适用于具有幂等属性的一些服务调用。
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)
<Length-Prefixed Message>
Response
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
Triple 协议支持同时运行在 HTTP/1 和 HTTP/2 协议之上,其包含以下两部分内容:
大部分的 RPC 调用都是 unary (request-response) 模式的,Triple HTTP RPC 协议 unary 模式能很好的满足后端服务间的数据传输需求。同时解决了gRPC协议的痛点,让浏览器、cURL 以及其他一些 HTTP 工具更容易的访问后端服务,即不需要借助代理和gRPC-web,使用标准的 HTTP 协议直接发起调用。
Triple HTTP RPC 同时支持 HTTP/1、HTTP/2 作为底层传输层协议,在实现上对应支持的 content-type 类型为 application/json、application/proto
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 设置:
如果 Content-Encoding 指定了相应值,则 payload 是被压缩过的,应该首先进行解压缩后再解析编码数据,Bare-Message 将作为 HTTP Body 在链路上传输。
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-protocol-version: 1.0.0
tri-service-version: 1.0.0
tri-service-group: dubbo
tri-service-timeout: 3000
[{"world"}]
对于成功 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 错误情况。
** 成功响应 **
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"}
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 Status Inferred Code 400 Bad Request invalid_argument 401 Unauthorized unauthenticated 403 Forbidden permission_denied 404 Not Found unimplemented 408 Request Timeout deadline_exceeded 409 Conflict aborted 412 Precondition Failed failed_precondition 413 Payload Too Large resource_exhausted 415 Unsupported Media Type internal 429 Too Many Requests unavailable 431 Request Header Fields Too Large resource_exhausted 502 Bad Gateway unavailable 503 Service Unavailable unavailable 504 Gateway Timeout unavailable all others unknown
Triple 协议的 Streaming 请求处理完全遵循 gRPC 协议规范,且仅支持 HTTP/2 作为传输层协议。并且后端服务间的 Unary 请求默认采用扩展版 gPRC 协议。
Triple 支持的 content-type 类型为标准的 gRPC 类型,包括 application/grpc、application/grpc+proto、application/grpc+json,除此之外,Triple 在实现上还扩展了 application/triple+wrapper 编码格式。
The following is the general sequence of message atoms in a GRPC request & response message stream
Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames.
以上即为 Triple 扩展版本的 gRPC 协议,更多详细规范说明请参照 gRPC 协议规范。