RPC调用失败情况分析
RPC 调用失败可以分为三种情况:
- RPC 请求还没有离开客户端
- RPC 请求到达服务器,但是服务器的应用逻辑还没有处理该请求
- 服务器应用逻辑开始处理请求,并且处理失败
最后一种情况是通过 server config 配置的重试策略来处理的,是本文主要讲解的内容
而对于前两种情况,gRPC 客户端会自动重试,与重试策略的配置并没有太大关系
因为这两种情况,服务端的逻辑并没有开始处理请求,所以始终可以重试,也被称为透明重试(transparent retries)
-
对于第一种情况,因为RPC没有离开客户端,所以可以一直重试,直到成功或者直到RPC的截止时间为止
-
对于第二种情况,虽然RPC 到达了服务端,但是应用逻辑并没有处理请求,所以,客户端会立即重试一次,如果再次失败, RPC 将根据配置的重试策略来进行处理
注意,这种情况可能会增加链路上的负载
下文介绍的重试限流只是为了防止服务器的应用逻辑服务过载,而这些重试并且不会进入应用逻辑层,所以他们不会把他们算作失败
同样透明重试也不会受到的重试配置 maxAttempts
限制
service config 简介
客户端的重试机制和重试限流都是通过 service config 来配置的,所以这里简单介绍一下 service config
service config 机制允许服务提供者发布参数,让其所有客户端自动使用
service config 的格式可以参考 grpc.service_config.ServiceConfig protocol buffer message, 未来可能会引入新的字段
会在其他文章中,讲一下服务端配置 service config 相关的知识
需要注意的是,service config 是和服务名称绑定的,客户端名称解析插件解析服务名,会返回解析的地址和 service config
名称解析返回给 grpc client 是 json 格式的 service config
客户端设置默认 service config
在客户端创建gRPC 连接时,通过DailOption 也可以配置一个默认的 service config
func WithDefaultServiceConfig(s string) DialOption
传递的参数是 json 格式化的字符串
客户端配置的默认service config 在使用上有一些限制:
- DialOption
WithDisableServiceConfig
被调用,会屏蔽掉服务器设置的 service config ,客户端会使用默认 service config - 当 name resolver 解析服务名称时,没有返回 service config 或者 返回一个
invalid service config
retryPolicy = `{
"methodConfig": [{
"name": [{"service": "grpc.examples.echo.Echo"}],
"waitForReady": true,
"retryPolicy": {
"MaxAttempts": 4,
"InitialBackoff": ".01s",
"MaxBackoff": ".01s",
"BackoffMultiplier": 1.0,
"RetryableStatusCodes": [ "UNAVAILABLE" ]
}
}]}`
_, err := grpc.Dial(*addr