今天将一个RMI部署到linux机器上,发现报错:
Connection refused to host: 127.0.0.2
因为在本机测试没有问题,所以怀疑还是跟服务器上的hostname-to-address mappings设置有关,于是去看服务器上的/etc/hosts文件,发现第一行为:
127.0.0.1 localhost 192.168.193.111
好像这个设置不太对,将其改成:
127.0.0.1 localhost
发现错误依旧,那127.0.0.2是怎么来的,往这个文件后面看,发现在文件的末尾又定义了一行:
127.0.0.2 linux-machine1.site linux-machine1
用hostname一查,发现这台机器的hostname就是linux-machine1,site是domain name,原来问题在这,将这一行comment掉,问题解决。
因为我是用的Spring的RmiServiceExporter来配置的RMI Server,所以debug的时候,可以先去日志文件看,一般有以下三行:
[INFO][rg.springframework.remoting.rmi.RmiServiceExporter][line:386][main] Looking for RMI registry at port '8008'
[INFO][rg.springframework.remoting.rmi.RmiServiceExporter][line:396][main] Could not detect RMI registry - creating new one
[INFO][rg.springframework.remoting.rmi.RmiServiceExporter][line:271][main] Binding service 'MyService' to RMI registry: RegistryImpl[UnicastServerRef [liveRef: [endpoint:[192.168.133.222:8008](local),objID:[0:0:0, 0]]]]
看看最后一行中粗体部分是不是显示的具体ip地址,如果是127.0.0.*之类的就会有问题。因为这个地址是要返回给rmi client,然后client根据这个地址去访问server side的。
因为如果没有在/etc/hosts特别指定,RmiServiceExporter里面缺省的是先去找hostname,然后通过hostname去找关联的ip address,可以通过”/sbin/ifconfig -a“命令来查看这个inet address。
RmiServiceExporter.prepare() -> LocateRegistry.getRegistry(int port) -> getRegistry(String host, int port, RMIClientSocketFactory csf)
line 141: host = java.net.InetAddress.getLocalHost().getHostAddress();
因为在我的hosts文件里多了一个hostname到127.0.0.2的映射,所以产生了开始的错误。去掉该映射,它就会去DNS中拿与本机对应的ip address。
最后,想了想,为什么会多了这么个127.0.0.2的映射,google了一下,因为我用的是Suse,好像这个系统会默认配置这么一个映射。
Note:上面提到的一些命令,都可以用图形化工具YaST来方便地查看和设置。