4 minutes reading time
前面的文章介绍了 gRPC 相关的功能,今天继续介绍 gRPC 的功能,本文将介绍 gRPC 的重试功能。
请求的重试是一个常见的功能,在我们日常的使用中,如果需要重试请求往往需要使用外部包进行实现,在gRPC 中内置了重试了功能,不需要我们自己实现。
通过查阅 gRPC 的文档可以看到,gRPC 会根据开发者设定的策略进行失败RPC的重试,有两种策略 1)重试策略:重试失败的RPC请求 2) hedging 策略:并行发生相同RPC请求。单个RPC请求可以选择两种重试策略中的一种,不能同时选择多种策略。
重试策略有以下参数可以使用:
hedging 策略可以主动发送单个请求的多个副本,而无需等待响应。需要注意的是,此策略可能会导致后端多次执行,因此最好仅对可以多次执行不会有不利影响的请求开启此策略。有如下参数:
一个请求在没有收到成功响应时,经过 hedgingDelay没收到响应 将继续发送请求,直至达到 maxAttempts 最大次数或请求成功。当收到成功响应时,所有未完成的其它请求将停止。本质上hedging 策略可以看作在收到失败响应前重试请求。
接下来讲解如何在 gRPC go语言版本中配置使用重试功能。
服务端创建一个服务,只有当请求次数达到第三次时,才返回成功响应。
package main
import (
"context"
"flag"
"fmt"
"log"
"net"
"sync"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
pb "github.com/overstarry/grpc-example/proto/echo"
)
var port = flag.Int("port", 9000, "port number")
type failingServer struct
func () error
func (ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error)
func main()
客户端通过 WithDefaultServiceConfig 设置配置好重试功能
package main
import (
"context"
"flag"
"log"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
pb "github.com/overstarry/grpc-example/proto/echo"
)
var (
addr = flag.String("addr", "127.0.0.1:9000", "the address to connect to")
// see https://github.com/grpc/grpc/blob/master/doc/service_config.md to know more about service config
retryPolicy = `{
"methodConfig": [{
"name": [{"service": "grpc.examples.echo.Echo"}],
"waitForReady": true,
"retryPolicy": {
"MaxAttempts": 4,
"InitialBackoff": ".01s",
"MaxBackoff": ".01s",
"BackoffMultiplier": 1.0,
"RetryableStatusCodes": [ "UNAVAILABLE" ]
}
}]}`
)
func retryDial() (*grpc.ClientConn, error)
func main()
接下来先启动服务端,再启动客户端,可以看到相应的日志:
2024/03/23 23:10:03 request failed count: 1
2024/03/23 23:10:03 request failed count: 2
2024/03/23 23:10:03 request succeeded count: 3
在客户端代码中我们可以看到相关的配置代码:
retryPolicy = `{
"methodConfig": [{
"name": [{"service": "grpc.examples.echo.Echo"}],
"waitForReady": true,
"retryPolicy": {
"MaxAttempts": 4,
"InitialBackoff": ".01s",
"MaxBackoff": ".01s",
"BackoffMultiplier": 1.0,
"RetryableStatusCodes": [ "UNAVAILABLE" ]
}
}]}`
retryPolicy 就是上文讲述的重试策略配置,name 表示对哪些RPC请求开启重试。
本文简单介绍了 gRPC 的重试功能及go语言如何实现重试功能,本文的相关代码可以在 https://github.com/overstarry/grpc-example 看到。