本文描述了gRPC如何处理错误,包括gRPC的内置错误状态码。可以在此处看到不同编程语言的示例代码。
正如在我们的概念文档和示例中所看到的,当gRPC调用成功并调用完成时,服务端会向客户端返回OK
状态(取决于编程语言,OK状态可能会也可能不会直接在代码中使用)。那么,如果调用不成功会发生什么?
如果发生错误,gRPC会返回其错误状态码,并带有可选的字符串错误消息,该消息提供有关所发生情况的更多详细信息。所有支持的编程语言中的gRPC客户端都可以使用错误信息。
标准错误模型是gRPC官方的错误模型,受所有gRPC客户端/服务端库的支持,并且独立于gRPC数据格式(无论是protocol buffers还是其他格式)。标准错误模型非常有限,并且不包括传达错误详情的能力。
但是,如果使用protocol buffers作为数据格式,则可能需要考虑使用Google开发和使用的更丰富的错误模型,如此处所述。此模型在服务端返回并在客户端消费额外的错误详情,这些错误详情由一个或多个protobuf消息表示。这种模型进一步指定了一组标准的错误消息类型,以满足最常见的需求(例如,无效参数、配额违规、堆栈跟踪等)。这些额外的错误详情的protobuf二进制编码在响应中作为尾随元数据提供。
这个更丰富的错误模型已经在C++,Go,Java,Python和Ruby库中得到支持,并且至少在grpc-web和Node.js的库中开了issue讨论需要实现它。如果有需求,其他编程语言库可能会在将来添加支持,如果感兴趣可以查看他们的github存储库。但请注意,用C语言编写的grpc-core
库不太可能支持它,因为它有目的实现为与数据格式无关(it is purposely data format agnostic)。
如果没有使用protocol buffers,可以使用类似的方法(在响应的尾随元数据中放置错误详情),这样的话,可能需要查找或开发用于访问此数据的库支持,以便在你编写的API中实际使用它。
在决定是否使用这样的扩展错误模型时需要注意一些重要的注意事项,包括:
队头阻塞(Head-of-line blocking或缩写为HOL blocking)在计算机网络的范畴中是一种性能受限的现象。它的原因是一列的第一个数据包(队头)受阻而导致整列数据包受阻。 例如它有可能在缓存式输入的交换机中出现,有可能因为传输顺序错乱而出现,亦有可能在HTTP流水线中有多个请求的情况下出现。
在许多情况下错误由gRPC引起,从网络故障到未经认证的连接,每一种错误都有与之相关联的特定的状态码。所有gRPC编程语言都支持以下的错误状态代码。
案例 | 状态码 |
---|---|
客户端应用取消请求 | GRPC_STATUS_CANCELLED |
在服务端返回状态时已超过截止日期 | GRPC_STATUS_DEADLINE_EXCEEDED |
服务端未找到对应方法 | GRPC_STATUS_UNIMPLEMENTED |
服务端宕机 | GRPC_STATUS_UNAVAILABLE |
服务端抛出异常(或者执行了除返回状态码以终止RPC之外的其他操作) | GRPC_STATUS_UNKNOWN |
案例 | 状态码 |
---|---|
在截止日期到期前,无数据传输或者传输了某些数据并且未检测到其他故障 | GRPC_STATUS_DEADLINE_EXCEEDED |
在连接中断之前已经传输了某些数据(例如,请求元数据已经被写入TCP连接中) | GRPC_STATUS_UNAVAILABLE |
案例 | 状态码 |
---|---|
无法解压缩但支持压缩算法 | GRPC_STATUS_INTERNAL |
客户端使用的压缩机制不受服务端支持 | GRPC_STATUS_UNIMPLEMENTED |
达到流量控制资源限制 | GRPC_STATUS_RESOURCE_EXHAUSTED |
流量控制协议违规 | GRPC_STATUS_INTERNAL |
解析返回状态出错 | GRPC_STATUS_UNKNOWN |
未认证:凭据无法获取元数据 | GRPC_STATUS_UNAUTHENTICATED |
主机集在认证元数据中无效 | GRPC_STATUS_UNAUTHENTICATED |
解析返回的protocol buffers时出错 | GRPC_STATUS_INTERNAL |
解析请求protocol buffers时出错 | GRPC_STATUS_INTERNAL |