开头
事情是这样的,领导安排我熟悉某个开发流程,意外发现了一个问题
经过
单元测试代码,用来测试这个频道页生成的逻辑,因为我们都是dubbo+zk的架构,涉及会调用一些下游生产者的接口,所以我在本地把生产者都启动起来。这样的话 我的本地是启动这生产者和消费者的程序。
当时的单元测试代码:
@Test
public void publishChannelStaticPage( ){
channelPublishAO.publishChannelStaticPage();
}
如果是正常的程序,单元测试是没有什么问题的,但是频道页生成的代码是在里面开了线程池,让线程池去并发的处理频道生成
问题其实就出在这个线程池上,因为main线程执行到这里开启了线程池,然后给线程池开始异步工作,这时候main方法顺着主分支走完流程关闭了,而线程池还没有完成工作,这就会导致线程池停止了工作,在调用生产者的过程中main线程跑完了消费者就自动断开了,导致生产者查出来数据,但是没有消费者了,没法返回出去。
生产者dubbo框架会抛出异常
具体异常信息:
2021-01-19 09:15:29.254 WARN 20532 --- [20880-thread-19] c.a.d.r.t.d.ChannelEventRunnable : [DUBBO] ChannelEventRunnable handle RECEIVED operation error, channel is NettyChannel [channel=[id: 0x00a5a6fe, /11.11.22.21:54360 :> /11.11.22.21:20880]], message is Request [id=18, version=2.0.0, twoway=true, event=false, broken=false, data=RpcInvocation [methodName=findTemplateById, parameterTypes=[class java.lang.Long], arguments=[972], attachments={path=com.mysteel.oilchem.website.service.WebsiteTemplateService, input=285, dubbo=2.5.3, interface=com.mysteel.oilchem.website.service.WebsiteTemplateService, version=255, timeout=30000}]], dubbo version: 2.5.3, current host: 127.0.0.1
com.alibaba.dubbo.remoting.RemotingException: Failed to send message Response [id=18, version=2.0.0, status=20, event=false, error=null, result=RpcResult [result=com.mysteel.oilchem.website.domain.TemplateDTO@10cbfa1, exception=null]] to /ip, cause: null
出现这种类型的问题一般就是在rpc远程调用过程中,消费者突然断开连接了或者连接时间超时了,生产者不知道该把数据返回给谁了。
解决方法
让main线程等待线程池异步方法完成,再结束main线程就可以正常了
@Test
public void publishChannelStaticPage( ) throws InterruptedException {
channelPublishAO.publishChannelStaticPage();
while (true){
Thread.sleep(10000);
}
}
多线程异步处理事务,要等异步的处理完成后再停止主线程,不然可能会产生意想不到的问题