weibocom / motan

A cross-language remote procedure call(RPC) framework for rapid development of high performance distributed services.
Other
5.88k stars 1.78k forks source link

DefaultResponseFuture#getValueOrThrowable抛出MotanServiceException #1063

Open SimonLiuhd opened 3 months ago

SimonLiuhd commented 3 months ago

当服务提供方第一次被调用的时候,DefaultResponseFuture#getValueOrThrowable抛出MotanServiceException,重启服务提供方或者客户端就能恢复,请帮忙看看什么情况会出现这种问题,有什么解决方法 谢谢。

IMG_8510

rayzhang0603 commented 3 months ago

可以看一下完整异常栈中最内层的caused by异常是什么。一般这种情况都是由IOException导致的,比如Broken pipe、Connection reset by peer之类的。

一般server端或者client端在还有读写操作时进行重启,就可能会出现这种io异常,避免的方式一般是server端在上下线(或者重启服务)时,可以参考优雅停止服务先关闭心跳开关,从注册中心下线服务节点后,在等待一小段时间(等当前请求都处理完毕后)在进行重启。

SimonLiuhd commented 3 months ago

@rayzhang0603 谢谢回复。

我们是采用directUrl的方式,请教这个怎么做优雅停止服务

rayzhang0603 commented 3 months ago

@rayzhang0603 谢谢回复。

我们是采用directUrl的方式,请教这个怎么做优雅停止服务

使用directUrl方式无法优雅停止服务。directUrl一般用在调试场景,生产场景建议使用zk等注册中心,这样可以支持服务扩缩容等动态调整能力。

SimonLiuhd commented 3 months ago

@rayzhang0603 完整堆栈如下。实际上APIResponse的类是有的。 帮忙再看看 st

rayzhang0603 commented 3 months ago

看异常栈,使用场景是client侧在线程池中调用rpc,反序列化时需要当前线程的类加载器可以加载到要反序列化的类。

rpc自身的机制不会影响类加载,要解决这个问题,还是确定线程池中的线程加载不到对应类的原因,可以确认一下有没有使用javaagent或者使用了定制的类加载器之类的,可以调试一下类加载的过程看看为什么加载不到这个类。

如果还是无法确定类加载失败的原因,可以考虑在首次请求前使用ReflectUtil.forName 预先加载一下rpc涉及的类试试,ReflectUtil有类缓存,只要加载成功一次就可以持续使用了。

SimonLiuhd commented 3 months ago

看异常栈,使用场景是client侧在线程池中调用rpc,反序列化时需要当前线程的类加载器可以加载到要反序列化的类。

rpc自身的机制不会影响类加载,要解决这个问题,还是确定线程池中的线程加载不到对应类的原因,可以确认一下有没有使用javaagent或者使用了定制的类加载器之类的,可以调试一下类加载的过程看看为什么加载不到这个类。

如果还是无法确定类加载失败的原因,可以考虑在首次请求前使用ReflectUtil.forName 预先加载一下rpc涉及的类试试,ReflectUtil有类缓存,只要加载成功一次就可以持续使用了。

@rayzhang0603 Motan可以进行更改增强吗?在Catch ClassNotFoundException的时候使用Class.forName(String)来加载。