(十六)优雅停机

dubbo的优雅停机,借助于java虚拟机的关闭钩子来实现。
打开关闭钩子需要配置dubbo启动参数dubbo.shutdown.hook为true,才会使用关闭钩子启用优雅停机。
在钩子里,调用dubbo的容器(有spring,log4j,jetty等容器,即com.alibaba.dubbo.container.Container的实现类)的stop方法,释放相关资源。
spring在关闭时,会调用bean的destroy方法,dubbo的bean是扩展spring的,dubbo的bean会实现spring的接口DisposableBean的destroy方法:
不管是service,还是reference,都会将停机标记destroyed属性设为true
service:

public void destroy() {
    if (isDestroyed()) {
        return;
    }
    destroyed = true;
    setAvailable(false);
}

reference:

public synchronized void destroy() {
    if (ref == null) {
        return;
    }
    if (destroyed){
        return;
    }
    destroyed = true;
    try {
        invoker.destroy();
    } catch (Throwable t) {
        logger.warn("Unexpected err when destroy invoker of ReferenceConfig(" + url + ").", t);
    }
    invoker = null;
    ref = null;
}

dubbo在调用服务时,会判断服务是否已经销毁,用一个destroyed标记来标明,下面源码:
com.alibaba.dubbo.rpc.protocol.AbstractInvoker<T>

public Result invoke(Invocation inv) throws RpcException {
    if(destroyed) {
        throw new RpcException("Rpc invoker for service " + this + " on consumer " + NetUtils.getLocalHost()
                                        + " use dubbo version " + Version.getVersion()
                                        + " is DESTROYED, can not be invoked any more!");
    }
    //other source code...
}

 

如果服务已经停用了,会抛出异常,客户端会根据配的集群策略调用其他的服务。

 


停机时:
客户端不再发起新的调用请求,新的调用请求都会报错,如果还有请求未返回结果,会等待一段时间(停机超时时间),超时则强制停机;
服务端不会接收新的请求,检查线程池是否还有任务未完成,有则等待一段时间(停机超时时间),超时则强制停机。

停机超时时间,dubbo默认是10秒,也可以配置指定超时时间:

# dubbo.properties
dubbo.service.shutdown.wait=10000


除了使用ShutdownHook,还可以通过调用:ProtocolConfig.destroyAll();

自己写了个RPC:

https://github.com/nytta

可以给个star,^0^.

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值