RPC实战与核心原理笔记<四>

RPC实战与核心原理笔记<四>

1、异常重试

1.1、为什么需要异常重试

当组装好数据,发起一次RPC调用的时候,由于网络抖动,导致RPC调用失败,如果此时距离超时时间还有一段距离,那么可以在可用的时间范围内,再重试一次,提高业务的可用率。

1.2、重试的一些注意事项

其实比起重试,最好还是不要重试,因为重试的局限性还是比较大。一方面需要保证业务的幂等性,也就是不论多少次调用,最终的结果都是一样的,如查询操作,更新操作,删除操作。另外重试的话,可能导致重试风暴,例如:
在这里插入图片描述
A调用B的时候,B需要调用C,假设B调用C失败,那么B会重试调用C,假设重试3次,那么假如3次都失败了,A重试调用B,再重试B,而B又要重试调用C三次,这样如果链路过长,必然造成重试风暴,因此这也是重试的业务需要注意的一个问题。

1.3、如何重试

利用do-while循环,或者递归,当抛出指定的可以重试的异常的时候,进行重试。重试的话,最好每次重新设置超时时间,如果时间已经到了,就直接抛出异常。
在重试的时候,一定要注意异常,可以设置一个重试异常的基类,然后其它可重试的异常均继承于该类,这样就可以根据异常判断是否可以重试,另外也可以设立一个异常的白名单,判断是否在报名单中,进而决定是否重试。

2、优雅关闭

当服务要重启或者关闭的时候,这个时候要保证已经接收的请求要处理完毕,新的请求不再接收,避免业务受损。那么如何实现优雅关闭呢?

2.1、优雅关闭流程

服务下线:进行反注册操作,注册中心会对相关conusmer下发配置,然后从健康列表中摘除这个节点。
在这里插入图片描述
但是仔细观察,这个这个过程其实涉及两次RPC调用,如果任意一次失败了(超时,其它原因),都会使得这个节点下线失败,最终流量还是会打在这个节点上。如果此时这个provider已经下线也就是关闭了端口,必然造成业务受损。其实大部分RPC框架都是这种机制,另外这个下线 / 反注册操作也应该无需手动操作,因为如果每个服务 / 实例都需要去服务治理平台上操作一下,还是够累的。
因此像大多数中间件一样,需要注册钩子函数,在JVM推出的时候,会发送一个信号,触发这个构造函数,在这个函数中完成相关的资源释放工作。
在这里插入图片描述
类似这么一段代码,然后在destory中完成反注册,关闭线程池,再最后关闭端口等操作。

2.2、一些额外的手段

刚才的下线逻辑,涉及两次RPC调用,降低了成功率,因为两次RPC任意一次失败,就会最终失败,那么能不能将两次RPC降为一次RPC调用呢?其实想法是这样的,当服务要下线的时候,再最后一次的调用中,服务端在响应报文中添加一些额外的数据,告知consumer,我这边要下线了,请不要再请求我了,这样的话,就没有注册中心什么事了。
但是这样的话,consuemr于provider之间又那么一点点耦合。其实业务调用就是相互耦合在一起的,这点也没有多大关系。

需要注意的是像kill -9这类操作是触发不了jvm的钩子函数的,需要注意。
其实对于非常重要的业务,还是先在治理平台上手动点击下线,然后观察日志有没有流量进来,确认没有流量进来后,再进行重启或者关闭,这是最可靠的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值