截止时间(deadline)
在以前接触的通信框架中,一般是通过超时时间(timeout)来指定客户端应用程序等待完成的时间(超出该时间后会以异常结束)。
与之不同的是,在 gRPC 中使用截止时间(deadline)。截至时间以请求开始的绝对时间来表示(尽管API将它们表示为持续时间的偏移),发起请求的应用程序设置截止时间,整个请求链需要在截止时间之前进行响应,否则会抛出异常。
截止时间和超时时间都是为了防止请求产生阻塞,造成大量请求挂起耗尽服务资源的情况。与超时时间不同的是,可以用到请求链的整个生命周期,而不必为每个请求单独设置。
gRPC 中是没有默认的截至时间的,这意味着如果客户端程序在开发时没有指定截止时间,那么它有可能会无限地等待自己请求的响应。(在实际实现上可能各种语言会设置一个默认截止时间,但由于 grpc 允许多个服务串行调用的特性,这一般也是一个很大的数值)。因此建议在开发 gprc 程序时设置截止时间。
取消
在一些场景下,我们还可以主动取消 gRPC 请求,同样可以避免让客户端一直等待。一旦取消 grpc 通信,就不能再进行消息传递,而且一方已经取消的消息也会传递到另一方。
错误处理
当发起 gPRC 调用时,客户端会接收成功状态的响应或者带有对应错误状态的错误。在编写客户端应用程序时,需要处理所有潜在的错误和错误条件。编写服务端应用程序也需要处理错误,并生成适当的错误状态码。
gRPC 中定义了一组专用状态码,具体如下。
gRPC状态码 | gRPC信息 | 含义 |
---|---|---|
0 | OK | 成功 |
1 | CANCELLED | 操作已被取消 |
2 | UNKNOWN | 未知错误 |
3 | INVALID_ARGUMENT | 客户端参数非法 |
4 | DEADLINE_EXCEEDED | 操作超过了截止时间 |
5 | NOT_FOUND | 请求实体未找到 |
6 | ALREADY_EXISTS | 客户端试图创建的实体已存在 |
7 | PERMISSION_DENIED | 调用者没有权限执行特定操作 |
8 | RESOURCE_EXHAUSTED | 资源已耗尽 |
9 | FAILED_PRECONDITION | 操作被拒绝,系统没有处于执行操作所需状态 |
10 | ABORTED | 操作被中止 |
11 | OUT_OF_RANGE | 操作超出了合法的范围 |
12 | UNIMPLEMENTED | 该操作未实现 |
13 | INTERNAL | 内部错误 |
14 | UNAVAILABLE | 服务当前不可用 |
15 | DATA_LOSS | 数据丢失或损坏 |
16 | UNAUTHENTICATED | 客户端没有进行操作的合法认证凭证 |
多路复用(multiplexing)
gRPC 允许在同一个 gRPC 服务端运行多个 gRPC 服务,也允许多个客户端存根(stub)使用同一个客户端连接,这种功能叫做多路复用(multiplexing)。
元数据(metadata)
在 gRPC 中信息通过远程方法的参数传递,但是有时候一些与业务上下文无关的数据我们并不希望放到参数中,这时候就要用的 gRPC 中的元数据,它的作用和 HTTP 中的报文头有些类似,可以用键-值对的形式存放一些数据。
拦截器(interceptor)
gRPC 中可通过拦截 RPC 执行,满足特定的需求,如日志、认证等,这会使用一种名为拦截器的扩展机制。
gRPC 中的拦截器按通信模式可以分为一元拦截器和流拦截器,按照使用的地方可以分为客户端拦截器和服务端拦截器。
需要注意的是,并非所有语言都支持 gRPC 拦截器,每种语言的拦截器实现也有差别。
安全性
gRPC 基于 HTTP/2 通信协议,支持使用TLS进行单向或双向加密。