几天线上发布,移动网关出现上万比的can not be invoke any more,好事多磨的是,业务方有人找过来说出现了同样的错误,具体错误示例如下
从错误看,是客户方发起调用时,dubbo会去检查本地的invoker instance,如果发现invoker已经是destroy status,则直接抛出上面的异常,下面先来说下平台部小伙伴曾遇到过的此异常情况
平台部小伙伴用springboot包装了一个dubbo的starter出来
该starter大多是基于注解的,如果同时在多个地方去实列化引用同一个远程服务的实列,就会出现此错误,究其原因,是因为spring在多次重复实列化时,会先去检查容器中是否已有相同的class实列存在,如果有,会先销毁旧,再去实列化一个新的,在销毁时会调用AbstractInvoker中的destroy方法。导致destroy属性被至为true,下面来看下该class的UML图
从上图可以看出,该Invoker是所有invoker的顶级父类所有的调用都会经过这里,但是任何对象的销毁也都会调用该类的destroy方法,到此我们可以来说说最上面的问题了,上面的问题都是在发布的时候才出现,分析原因最大可能是运维GG在stop服务前,没有将其从nginx上摘除,在停服务的过程中,要先进行资源的销毁,但是此时8080端口依然对外可用(也就是服务),如果此时有流量进来发起调用,就会抛出上面的异常了