异常重试
-
调用失败的情况
- 第一种:客户端请求异常,此时未达到服务端
- 第二种:请求达到服务端,但是服务端并未处理此请求
- 第三种:服务端处理请求,但是处理结果是失败
-
对于第一种和第二种gRPC客户端会自动重试,因为服务端并未处理,所以始终可以重试(透明重试transparent retries),第三种需要手动设置重试策略
//在客户端设置重试策略( 新建重试配置retry.json) 1. name 指定需要配置异常重试的RPC方法,service是必填项,method是可选项 2. retryPolicy 指定重试策略 2.1 maxAttempts 最大重试次数,指定一次RPC 调用中最多的请求次数,包括第一次请求。必须是大于 1 的整数,对于大于5的值会被视为5。 如果设置了调用的过期时间,那么到了过期时间,无论重试情况都会返回超时错误DeadlineExceeded 2.2 retryableStatusCode 重试状态码,当 RPC 调用返回非 OK 响应,会根据 retryableStatusCode 来判断是否进行重试, GRPC并没有提供自定义CODE的功能,所以只能用内置的CODE 2.3 initialBackoff,maxBackoff,backoffMultiplier 指数退避参数,在进行下一次重试请求前,会计算需要等待的时间。 必须指定,并且必须具有大于0。第一次重试间隔是random(0, initialBackoff), 第 n 次的重试间隔为random(0, min( initialBackoff*backoffMultiplier**(n-1) , maxBackoff)) { "methodConfig": [ { "name": [ { "service": "cn.jannal.grpc.facade.dto.HelloService", "method": "hello" } ], "retryPolicy": { "maxAttempts": 5, "initialBackoff": "0.5s", "maxBackoff": "30s", "backoffMultiplier": 2, "retryableStatusCodes": [ "UNAVAILABLE" ] } } ] }
-
客户端重试配置代码
@Slf4j public class GrpcConsumerRetry { public static final String IP = "127.0.0.1"; public static final int PORT = 8082; @Test public void testRetry() { ManagedChannel channel = ManagedChannelBuilder.forAddress(IP, PORT) .defaultServiceConfig(getRetryingServiceConfig()) .enableRetry() // 重要,客户端是默认关闭了重试的 .usePlaintext()// 启用明文 .build(); // 同步调用 HelloServiceGrpc.HelloServiceBlockingStub stub = HelloServiceGrpc.newBlockingStub(channel); HelloResponse helloResponse = stub.hello(HelloRequest.newBuilder() .setFirstName("Jannal") .setLastName("Jan") .build()); log.info("Response received from server:{}", helloResponse); channel.shutdown(); } protected static Map<String, ?> getRetryingServic