背景
rpc请求的时候,上游调用下游,如果失败了希望能够重试,如果每个业务代码都自己写一遍调用不同下游的代码,过于繁琐
需要有一个重试的组件,封装所有上游调用下游的请求,支持重试
定义
适用场景:后续调用不通,而不是下游返回了失败之类的结果,只要下游返回结果则代表链路通畅
retry: 次数
retry_interval: 重试之间休息的时间
实体名称
upstream:上游
downstream:下游
methodName:方法名
上游可以根据需要更加细化,比如包含cluster名称等
实现
配置重试
重试次数
即用一个分布式服务框架,如zk等,写一个特定key
如/retry/upstream/downstream/methodName
值为正整数
为10则代表upstream调用downstream的methodName这个方法时,最多重试10次
重试间隔
/retry_interval/upstream/downstream/methodName
值为正整数,单位为ms
为1000代表每次重试间隔1s
重试生效,读配置
框架上用middleware,切面等方式(我是以py的django框架为基础,其他语言也有自己的框架),该中间件的处理在upstream调用下游的时候
比如upstream在调用downstream的方法methodName的时候,
会去访问分布式配置的key,记录retry和retry_interval
py伪代码
cnt = 0
while cnt < retry:
if cnt >= 1
time.sleep(retry_interval)
cnt+=1
try:
res = doRequest(req)
except Exception,e:
last_error = e
if res is not None:
return res
raise last_error
思考
1.和前面服务治理组件之间的先后顺序关系
仁者见仁,建议设置顺序为先ACL,degradation,再走retry
2.调用失败,异常和返回失败,异常的关系
调用失败,异常相当于链路没有走通,可能是网络等原因,此种情况框架做重试
返回失败,异常则基本上是链路走通,且很有可能是符合预期的,此种情况框架不做重试,需要自行定位上下游代码原因
3.重试的变种
上面重试是直接失败了就睡n秒,可以在此基础上附加很多东西
如时间窗口计算失败率,如果失败率>0.05就不重试了认为下游不稳定
另外sleep时间也可以不断的乘2,类似这种