首页 > 其他分享 >Golang gRPC学习(05): retry重试

Golang gRPC学习(05): retry重试

时间:2023-07-28 17:13:01浏览次数:36  
标签:retry 请求 service 05 grpc 重试 InitialBakckoff config

什么是重试

如果服务出现了错误,主要是网络,服务器出现了短暂异常的时候,该怎么办?
我们都会人工或者自动的重新连接服务试试,看服务是否恢复可用了。

这种重新进行连接服务的一种方式就是重试。如果是在微服务里,应该属于微服务治理的范畴。
重试是处理网络服务出现暂时不可用的一种方法。

怎么进行重试

第一:你要能知道网络出现了错误。
怎么才能知道网络出现了错误呢?
一种是你主动探测网络是否可用,比如说健康检查;一种是根据定义的错误码来进行重试。比如http的一些错误码。

第二:根据上面的探测或者错误码决定是否重试。
因为不是所有的错误都要进行重试,我们要根据具体情况来做决定是否重试。

第三:重试的策略
就是怎么进行重试。
在gRPC的这份设计中,主要有2中重试策略:

  1. Retry Policy,出错时立即重试

  2. Hedging Policy,定时发送并发的多个请求,根据请求的响应情况决定是否发送下一个同样的请求,还是返回(好像该策略目前未实现)

  3. 在Retry和Heading基础上的限流

客户端的重试策略和限流策略都是用一个配置文件配置 - service config,这个配置文件用proto定义了一些字段和格式,文件在 grpc/service_config/service_config.proto 中,它最终会解析为一个json格式,proto->json 规则文档

一些Service Config文档例子:doc/service_config

例子

参考官方的例子把我们前面的hello word程序用retry策略改写下。

客户端

主要是要在 Dial() 建立连接的这个函数里加一个参数 grpc.WithDefaultServiceConfig() ,这个就是配置重试策略的参数。

conn, err := grpc.Dial(Address, grpc.WithInsecure(),grpc.WithDefaultServiceConfig(retryPolicy))

里面的参数 retryPolicy 是一个json的字符串,这个就是service config:

retryPolicy = `{
        "methodConfig":[{
           "name":[{"service": "grpc-tutorial.05retry.hello.hello"}],
           "waitForReady": true,
           "retryPolicy": {
                "MaxAttempts": 4,
                "InitialBakckoff": ".01s",
                "MaxBackoff": ".01s",
                "BackoffMultiplier": 1.0,
                 "RetryableStatusCodes": ["UNAVAILABLE"]
            }
    }]}`
  • MaxAttempts:
    最多请求次数。这里设置为4,一次原始请求,三次重试请求。

MaxAttempts必须是大于1的整数,对于大于5的值会被视为5。

  • InitialBakckoff, BackoffMultiplier, MaxBackoff
    这3个参数要结合看, 意思是在进行下一次重试请求前,会计算需要等待的时间,计算公式为:
    • 第一次重试间隔是 random(0, InitialBakckoff)
    • 第 n 次的重试间隔为 random(0, min( InitialBakckoff*BackoffMultiplier*(n-1) , MaxBackoff ))

InitialBakckoff 和 MaxBackoff 必须指定,并且必须具有大于0。
BackoffMultiplier 必须指定,并且大于零。

  • RetryableStatusCodes
    会根据这个 RetryableStatusCodes 来判断是否进行重试。这里设置为 UNAVAILABLE,会根据这个状态来进行重试。

retryableStatusCodes 必须制定为状态码的数据,不能为空,并且没有状态码必须是有效的 gPRC 状态码,可以是整数形式,并且不区分大小写 ([14], [“UNAVAILABLE”], [“unavailable”)

服务端

在服务端我要制造重试的情况出来,主要是 failRequest() 这个函数,改写一下程序:

type failServer struct {
    pb.UnimplementedHelloServer
    mu sync.Mutex

    reqNum uint
    reqMax uint
}

func (f *failServer) failRequest() error {
    f.mu.Lock()
    defer f.mu.Unlock()
    f.reqNum++
    if (f.reqMax > 0) && (f.reqNum % f.reqMax == 0) {
        return nil
    }
    return status.Errorf(codes.Unavailable, "failRequest: failing it")
}

然后在main函数初始化一下这个failServer struct:

failService := &failServer{
        reqNum: 0,
        reqMax: 4,
}

完整的例子在:这里github

运行看看:
先运行服务端:go run server/main.go

在运行客户端:GRPC_GO_RETRY=on go run client/main.go

注意:

运行客户端一定要在环境变量里加上 GRPC_GO_RETRY=on

可是报错了:
sayhello err: rpc error: code = Unavailable desc = failRequest: failing it
exit status 1

而且服务端也只打印了一条信息:
request failed num: 1

标签:retry,请求,service,05,grpc,重试,InitialBakckoff,config
From: https://www.cnblogs.com/jiujuan/p/17588382.html

相关文章

  • 三维空间中的刚体运动、MPU6050、DMP姿态解算、卡尔曼滤波
    坐标系空间中三个正交的轴组成,构成线性空间的一组基($......
  • Java学习Day05
    4.2.1、语法格式for(初始化表达式;循环条件;条件控制语句){执行语句………}在上面的语法结构中,for关键字后面()中包括了三部分内容:初始化表达式、循环条件和条件控制语句,它们之间用“;”分隔,{}中的执行语句为循环体。注意:(1)for(;;)中的两个;是不能多也不能少(2)循环条件......
  • Java并发(十四)----悲观互斥与乐观重试
    1.悲观互斥互斥实际是悲观锁的思想例如,有下面取款的需求interfaceAccount{  //获取余额  IntegergetBalance();​  //取款  voidwithdraw(Integeramount);​  /**  *方法内会启动1000个线程,每个线程做-10元的操作  *如......
  • 【报错修复】HRESULT: 0x80070057 The library hostfxr.dll was found, but loading i
    我写了一个winform程序,拷贝到win7系统上,提示需要下载.net给的链接是https://aka.ms/dotnet-core-applaunch?missing_runtime=true&arch=x64&rid=win7-x64&apphost_version=5.0.3&gui=true这台win7上不了网我用win10下载了这个链接的桌面运行时windowsdesktop-runtime-5.0......
  • 钳形表校准仪TD1050钳形表校准装置
    钳形表校准仪TD1050是一台用于校准多功能钳形表的装置,集交直流大电流标准源、交直流电压标准源和电阻标准源等功能于一体,兼具交直流功率输出功能,可满足不同精度等级的多功能钳形表的校准需求。2.钳形表校准仪TD1050产品特征直流电流输出:10mA~1050A(2100A选件)交流电流输出:10......
  • 提示:进程已结束,退出代码-1073741819 (0xC0000005)
    问题描述:idea运行程序闪退,显示——进程已结束,退出代码-1073741819(0xC0000005)问题原因:Idea和金山词霸的划词功能不能同时打开。(发现这个原因的时候,挺无语的,说实话) Idea和金山词霸的划词功能不能同时打开......
  • Verilog-1995,2001,2005差异
    1、Verilog不同版本的差异下图是Verilog各个阶段的关键字列表:2、Verilog-1995VSVerilog-20011、模块声明的扩展(1)       Verilog‐2001允许将端口声明和数据类型声明放在同一条语句中,例子如下: (2)Verilog‐2001中增加了ANSIC风格的输入输出端口声明,可以用于module,t......
  • CF1053E-Euler Tour题解
    前言还是一道神仙题很难想题面luogu上copy的样例解释懒得翻,我觉得应该都看得懂样例吧。题面翻译现有一棵\(n\)个点的形态未知的树,给定其长度为\(2n-1\)的欧拉序的一部分请根据给出的残缺的欧拉序还原出一个完整的欧拉序或判断不存在这样的树输入中用非零数字表示欧拉......
  • java 接口调用重试
    Java接口调用重试实现引言在实际开发中,我们经常会遇到网络不稳定、接口调用超时等问题,这时我们需要实现接口调用的重试机制,来保证接口的可靠性和稳定性。本文将介绍如何在Java中实现接口调用重试。流程概述下面是实现接口调用重试的整个流程概述:步骤描述1.发起接......
  • 005--验证码及应用于登录案例,idea技巧之开启热部署..
    参考:SpringBoot|稀客大大(heyige.cn)自勉:勤则百病皆消,懒则诸事不顺1.idea技巧之-定位已经打开的代码,在文件夹中的位置2.idea技巧之-在idea上改变数据库表最后别忘记点击OK3.验证码使用依赖<dependency><groupId>com.github.whvcse</groupId><artif......