04-错误处理和调试

本文描述了gRPC如何处理错误,包括gRPC的内置错误状态码。可以在此处看到不同编程语言的示例代码。

0.1. 标准错误模型

正如在我们的概念文档和示例中所看到的,当gRPC调用成功并调用完成时,服务端会向客户端返回OK状态(取决于编程语言,OK状态可能会也可能不会直接在代码中使用)。那么,如果调用不成功会发生什么?

如果发生错误,gRPC会返回其错误状态码,并带有可选的字符串错误消息,该消息提供有关所发生情况的更多详细信息。所有支持的编程语言中的gRPC客户端都可以使用错误信息。

0.2. 更丰富的错误模型

标准错误模型是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中实际使用它。

在决定是否使用这样的扩展错误模型时需要注意一些重要的注意事项,包括:

  • 在错误详情有效负载的期望和需求方面,扩展错误模型的库实现可能与编程语言之间不一致
  • 已有的代理服务器,日志记录器和其他标准HTTP请求处理器无法查看错误详情,因此无法将其用于监视或其他目的
  • 在尾部追加接口中的额外的错误详情将会出现队头阻塞(Head-of-line blocking,HOL blocking),并且,由于更频繁的缓存未命中会降低HTTP/2报头的压缩效率
  • 更大的错误详情有效负载可能会遇到协议限制(例如,最大标头大小限制),从而丢失原始错误

队头阻塞(Head-of-line blocking或缩写为HOL blocking)在计算机网络的范畴中是一种性能受限的现象。它的原因是一列的第一个数据包(队头)受阻而导致整列数据包受阻。 例如它有可能在缓存式输入的交换机中出现,有可能因为传输顺序错乱而出现,亦有可能在HTTP流水线中有多个请求的情况下出现。

0.3. 错误状态码

在许多情况下错误由gRPC引起,从网络故障到未经认证的连接,每一种错误都有与之相关联的特定的状态码。所有gRPC编程语言都支持以下的错误状态代码。

0.3.1. 一般错误

案例状态码
客户端应用取消请求GRPC_STATUS_CANCELLED
在服务端返回状态时已超过截止日期GRPC_STATUS_DEADLINE_EXCEEDED
服务端未找到对应方法GRPC_STATUS_UNIMPLEMENTED
服务端宕机GRPC_STATUS_UNAVAILABLE
服务端抛出异常(或者执行了除返回状态码以终止RPC之外的其他操作)GRPC_STATUS_UNKNOWN

0.3.2. 网络故障

案例状态码
在截止日期到期前,无数据传输或者传输了某些数据并且未检测到其他故障GRPC_STATUS_DEADLINE_EXCEEDED
在连接中断之前已经传输了某些数据(例如,请求元数据已经被写入TCP连接中)GRPC_STATUS_UNAVAILABLE

0.3.3. 协议错误

案例状态码
无法解压缩但支持压缩算法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
上次修改: 14 April 2020