Golang gRPC学习(05): retry重试
什么是重试
如果服务出现了错误,主要是网络,服务器出现了短暂异常的时候,该怎么办?
我们都会人工或者自动的重新连接服务试试,看服务是否恢复可用了。
这种重新进行连接服务的一种方式就是重试。如果是在微服务里,应该属于微服务治理的范畴。
重试是处理网络服务出现暂时不可用的一种方法。
怎么进行重试
第一:你要能知道网络出现了错误。
怎么才能知道网络出现了错误呢?
一种是你主动探测网络是否可用,比如说健康检查;一种是根据定义的错误码来进行重试。比如http的一些错误码。
第二:根据上面的探测或者错误码决定是否重试。
因为不是所有的错误都要进行重试,我们要根据具体情况来做决定是否重试。
第三:重试的策略
就是怎么进行重试。
在gRPC的这份设计中,主要有2中重试策略:
Retry Policy,出错时立即重试
Hedging Policy,定时发送并发的多个请求,根据请求的响应情况决定是否发送下一个同样的请求,还是返回(好像该策略目前未实现)
在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
Golang gRPC学习(05): retry重试的更多相关文章
- Golang gRPC学习(04): Deadlines超时限制
为什么要使用Deadlines 当我们使用gRPC时,gRPC库关系的是连接,序列化,反序列化和超时执行.Deadlines 允许gRPC客户端设置自己等待多长时间来完成rpc操作,直到出现这个错误 ...
- golang——gRPC学习
1.获取gRPC 环境变量GOPATH的src目录下执行: git clone https://github.com/grpc/grpc-go.git google.golang.org/grpc g ...
- Golang gRPC学习(03): grpc官方示例程序route_guide简析
代码主要来源于grpc的官方examples代码: route_guide https://github.com/grpc/grpc-go/tree/master/examples/route_gui ...
- gRPC学习之三:初试GO版gRPC开发
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- gRPC学习
概述 gRPC 一开始由 google 开发,是一款语言中立.平台中立.开源的远程过程调用(RPC)系统. 在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法, ...
- gRPC学习之一:在CentOS7部署和设置GO
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- gRPC学习之二:GO的gRPC开发环境准备
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos gRPC学习系列文章链接 在CentOS7部署和设置G ...
- gRPC学习之四:实战四类服务方法
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- gRPC学习之五:gRPC-Gateway实战
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Golang 语法学习笔记
Golang 语法学习笔记 包.变量和函数. 包 每个 Go 程序都是由包组成的. 程序运行的入口是包 main. 包名与导入路径的最后一个目录一致."math/rand" 包由 ...
随机推荐
- [转帖]xtrabackup2.4备份恢复脚本
https://developer.aliyun.com/article/534230#:~:text=xtrabackup2.4%E5%A4%87%E4%BB%BD%E6%81%A2%E5%A4%8 ...
- rclone 的下载地址-官方网站
Downloads Rclone is single executable (rclone, or rclone.exe on Windows) that you can simply downloa ...
- [转帖]从理论到实践,异步I/O模式下NVMe SSD高性能之道
在早期NVMe的讨论话题中,常常将之AHCI协议进行对比,在支持的最大队列深度.并发进程数以及消耗时钟周期数等方面,NVMe吊打了AHCI.最直观也最权威的就是下面这张对比图片. NVMe与AHCI协 ...
- [转帖]01-rsync备份方式
https://developer.aliyun.com/article/885783?spm=a2c6h.24874632.expert-profile.284.7c46cfe9h5DxWK 简介: ...
- 使用TFS CI 又想保留服务运行状态的简单方法
最近公司使用TFS-CI的方式定期部署测试环境, 但是发现TFS-CI 运行完之后会清理agent所在的测试环境. 运行的进程都会被killed 1. 第一种方法: 本来第一反应 是使用systemd ...
- CPU 大拿的作品
http://nieyong.github.io/wiki_cpu/index.html 改天学习写一下.
- [LeetCode刷题记录]113 路径总和 II
题目描述 给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径. 说明: 叶子节点是指没有子节点的节点. 难度 中等 题解 采用深度搜索优先,遍历每条从根节点到叶子节点的 ...
- 剪粘板增强小工具(可多次Ctrl+V)
前言 windows的剪贴板中存储是的最新一次的复制结果,比如先复制A,再复制B,C,在按下粘贴键时粘贴的是最后一次的结果C,在工作时有时候会遇到需要多次复制粘贴的情景,我就在思考有没有一款工具可以保 ...
- Docker 安装 Nacos 注册中心
废话不多说直接上安装脚本: 在运行安装脚本之前,首先,我们查看一下 Nacos 的版本分别有哪些使用 docker search nacos: 然后在执行: docker pull nacos/nac ...
- 从github上下载代码到本地
相关链接: 码云(gitee)配置SSH密钥 码云gitee创建仓库并用git上传文件 git 上传错误This oplation equires one of the flowi vrsionsot ...