最近在作一個項目,這個項目裏有兩個系統。這是背景!java
這兩個系統不能互相訪問!這是坑爹的需求!spring
而後我不想使用數據庫共享,也不但願用rest的方式,因此我想到了用dubbo來解決!這是個人解決方案!數據庫
<!-- 提供方應用信息,用於計算依賴關係 --> <dubbo:application name="projectA"/> <!-- 用dubbo協議暴露服務 --> <dubbo:protocol name="rmi" port="20881"/> <!-- 使用暴露服務地址 --> <dubbo:registry id="projectARegistry" address="zookeeper://192.168.72.232:2181"/> <!-- 註冊服務 --> <dubbo:service interface="com.company.demo.service.DemoService" ref="demoServiceImpl" registry="projectARegistry"/>
<dubbo:application name="projectB"/> <dubbo:registry address="zookeeper://192.168.72.232:2181"/> <dubbo:registry id="projectARegistry" address="zookeeper://192.168.72.232:2181"/> <!-- DemoService獲取 --> <dubbo:reference interface="com.company.demo.service.DemoService" id="demoServiceImpl" registry="projectARegistry"/>
坑爹的錯誤立刻就要出現了!vim
[http-bio-8080-exec-7] WARN o.s.remoting.rmi.RmiProxyFactoryBean- Could not connect to RMI service [rmi://192.168.72.235:20881/com.company.demo.service.DemoService] - retrying
我找了好久好久,終於在一個很不起眼的地方發現了一段代碼。tomcat
Caused by: org.springframework.remoting.RemoteConnectFailureException: Could not connect to remote service [rmi://192.168.72.235:20881/com.ztesoft.zsmartcity.ynzw.demo.service.DemoService]; nested exception is java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is: java.net.ConnectException: 拒絕鏈接 at org.springframework.remoting.rmi.RmiClientInterceptorUtils.convertRmiAccessException(RmiClientInterceptorUtils.java:150) at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:348) at org.springframework.remoting.rmi.RmiClientInterceptor.refreshAndRetry(RmiClientInterceptor.java:331) at org.springframework.remoting.rmi.RmiClientInterceptor.handleRemoteConnectFailure(RmiClientInterceptor.java:307) at org.springframework.remoting.rmi.RmiClientInterceptor.invoke(RmiClientInterceptor.java:263) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) at com.sun.proxy.$Proxy64.list(Unknown Source) at com.alibaba.dubbo.common.bytecode.Wrapper0.invokeMethod(Wrapper0.java) at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:46) at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:72) at com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol$2.doInvoke(AbstractProxyProtocol.java:93) at com.alibaba.dubbo.rpc.protocol.AbstractInvoker.invoke(AbstractInvoker.java:144) at com.alibaba.dubbo.rpc.listener.ListenerInvokerWrapper.invoke(ListenerInvokerWrapper.java:74) at com.alibaba.dubbo.rpc.protocol.dubbo.filter.FutureFilter.invoke(FutureFilter.java:53) at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91) at com.ztesoft.zsmart.pot.dubbo.filter.ConsumerTraceFilter.invoke(ConsumerTraceFilter.java:36) at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91) at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:74) at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91) at com.alibaba.dubbo.rpc.filter.ConsumerContextFilter.invoke(ConsumerContextFilter.java:48) at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91) at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:53) at com.alibaba.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:77) ... 74 more
我特麼何時寫了127.0.0.1
這個地址的,我擦嘞!!!並且明明獲取的是rmi://192.168.72.235:20881/com.company.demo.service.DemoService
這個啊。服務器
遇到這種叼問題第一個想到的就是debugapp
我先是在服務註冊的地方,講協議格式改爲:ide
<dubbo:protocol name="rmi" port="20881" host="192.168.72.235"/> 192.168.72.235是服務提供者所在服務器的ip
他媽的,發現dubbo在某一個位置,講個人url的ip給改了,以下:url
private void exportLocal(URL url) { if (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) { // 他孃的,設置成127.0.0.1了 URL local = URL.valueOf(url.toFullString()).setProtocol(Constants.LOCAL_PROTOCOL).setHost(NetUtils.LOCALHOST).setPort(0); // rest ServiceImplHolder.getInstance().pushServiceImpl(ref); // rest end Exporter<?> exporter = protocol.export(proxyFactory.getInvoker(ref, (Class) interfaceClass, local)); exporters.add(exporter); logger.info("Export dubbo service " + interfaceClass.getName() + " to local registry"); } }
好了,沒辦法,搞不定,總不能去改dubbo的代碼吧。。。idea
而後我就用Naming去獲取上面那個rmi://...
Object obj = Naming.lookup("rmi://192.168.72.235:20881/com.company.demo.service.DemoService");
發現果真被坑了,獲取的類是代理出來的,裏面果真有個127.0.0.1
NetUtils
中的getLocalAddress0
這個方法127.0.0.1
的那個ipvim /etc/hosts
192.168.72.235 localhost hostname # 192.168.72.235 服務器ip # localhost # hostname 是主機名,在/etc/sysconfig/network進行配置
重啓服務提供者服務,完美解決問題!!!