最近项目遇到一个奇怪的问题,项目是一个Web应用,采用Dubbo RPC框架实现业务流程与原子服务的分离,其中,部分原子服务由两家或以上的供应商系统提供。因业务场景要求,同一个请求需要同时调用多个供应商的原子服务(即多个服务提供者)。在本地windows开发环境使用Tomcat部署测试没有问题,但在Linux上使用Weblogic 12c部署时,在某些时候出现Dubbo调用原子服务响应始终失败的情况。
原因:实现同一个请求同时调用多个服务提供者的方式是自定义了dubbo的MergeableClusterInvoker和ForkingClusterInvoker,前者表示调用多个服务提供者的服务并获取所有返回结果,后者表示调用多个服务提供者的服务但只获取最快返回的结果。自定义的两个类具有和dubbo.jar中相同的签名,即在同一个应用中存在有包名com.alibaba.dubbo.rpc.cluster.support和类名完全相同的类。在打包部署时,按照公司惯例,将工程源码src编译打包为jar包放到了WEB-INF/lib下,jar包名称(例如app.jar)按字母顺序排在dubbo.jar之前。一直认为在类加载时,对于同一个路径下的包应该按照字母排序进行加载,因此可以加载到自定义的两个类。然而,项目先后在Tomcat和Weblogic部署运行均正常,但在测试阶段在某一台weblogic服务器部署后,dubbo RPC调用始终无法成功,最终定位是运行时没有走自定义的MergeableClusterInvoker类,而是使用了dubbo.jar中的该类。该问题在不同服务器上重试会有不同的情况,有时可以成功加载自定义类,有时不行。
解决:删除dubbo.jar包中相同签名的类。
遗留疑问: 难道Weblogic加载WEB-INF/lib下的jar包时,顺序是随机的?与文件系统有关系?