18.重试、provider下线、网络断开等容错怎么实现
case构造的方式
可以在DubboInvoker.doInvoke打断点,然后让provider下线,然后再继续执行刚才断点停住的地方等等构造异常场景。
如果有provider服务停掉, consumer端如何感知?再次启动刚停掉的provider呢
provider停掉会触发zk客户端的监听,监听对客户端的invoker列表进行刷新。
再次启动会触发 zk的监听,代码在ZkclientZookeeperClient
public IZkChildListener createTargetChildListener(String path, final ChildListener listener) {
return new IZkChildListener() {
public void handleChildChange(String parentPath, List<String> currentChilds)
throws Exception {
listener.childChanged(parentPath, currentChilds);
}
};
}
然后再触发 com.alibaba.dubbo.registry.support.FailbackRegistry.doNotify(URL, NotifyListener, List)。
com.alibaba.dubbo.registry.integration.RegistryDirectory.refreshInvoker(List), 这是在zk的event线程完成的。
如果有provider停掉了 走一样的监听逻辑
同时,dubbo支持 定时检查provider的状态并进行重连,具体参见
com.alibaba.dubbo.remoting.transport.AbstractClient.initConnectStatusCheckCommand()
reconnectExecutorService.scheduleWithFixedDelay(connectStatusCheckCommand, reconnect, reconnect, TimeUnit.MILLISECONDS);
如果正在发服务的时候,provider停掉了,dubbo是如何处理的?
如果在发服务时,provider停掉了,那么此时会抛出异常,并在FailoverClusterInvoker doInvoke中捕获,
FailoverClusterInvoker支持调用失败时重试(可配置),此时达到再次重试的目的。
配置获取的代码:
com.alibaba.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(Invocation, List<Invoker
int len = getUrl().getMethodParameter(invocation.getMethodName(), Constants.RETRIES_KEY, Constants.DEFAULT_RETRIES) + 1;
client在多次调用时,与provider端的连接是建立几次,在prodvider端服务状态有变化时呢?
NettyClient 的doOpen doConnect均在初始化的时候调用,有几个provider就调用几次,真正rpc调用服务的时候是不会再调用open与connect的。
上面这个说法不严格,因为看他发送消息的代码就知道了,每次发消息时还会检查下:
public void send(Object message, boolean sent) throws RemotingException {
if (send_reconnect && !isConnected()){
connect();
}
Channel channel = getChannel();
//TODO getChannel返回的状态是否包含null需要改进
if (channel == null || ! channel.isConnected()) {
throw new RemotingException(this, "message can not send, because channel is closed . url:" + getUrl());
}
channel.send(message, sent);
}
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!