解决RMI服务在windows下正常调用,而在linux下异常问题
现象: 端口开了访问不到,报错日志如下:
引用
java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused: connect
问题解决:
检查服务端线程信息
netstat -ao 查看线程信息如下:
引用
Proto Recv-Q Send-Q Local Address Foreign Address State Timer
tcp 0 0 *:10011 *:* LISTEN off (0.00/0/0)
从这里可以看到,服务已经启动,但是没有客户端连接
Timer 这项的含义如下:
Timer state may now be either on or off. The time (in seconds) being displayed is how long it willtake the timer to expire. All these options are subject to be removed in later releases of the NET software.
更多详情可以看这里:
http://www.blogjava.net/aoxj/archive/2008/02/22/181321.html
2. 检查客户端和服务端网络连接,此项检查包括服务端防火墙是否开启(开启了有可能禁用10011端口)
telnet IP 端口
只要能连接可以排除网络问题。
此处忽略了一个重要的信息,日志显示的不太符合常理,访问远端服务器连接不到,应该返回服务器的IP,结果却返回了一个127.0.0.1
上网google了一把,才知道linux下解析主机名的逻辑和windows下不同:
RMI的调用原理是首先Server会返回一个绑定对象,让客户端像调用本地方法一
样调用远程服务,客户端程序向服务端请求一个对象的时候,返回的stub对象里面包含了服务器的hostname,客户端的后续操作是根据这个hostname来连接服务器端。在server端返回的绑定对象中采用的是server主机名。可以在服务器端运行
引用
hostname -i
验证,如果返回的是127.0.0.1,则表示会去调用本机的服务,必然会报错的
而在windows机器上127.0.0.1应该也是可以返回服务器ip的
找到这个原因后,
修改host
运行
引用
sh /etc/init.d/network restart
重启was 服务器,一切OK了
总结:
方法论
分析问题时,先从自己身上找问题。
1.对发现的不正常的日志要注意,例如这里的报错IP不正确。
2.分步骤解决,是否是服务器端的问题,是否是客户端的问题,是否是网络问题。找出每个3.步骤的最简单的验证方法,怀疑是环境问题,写个最简单的helloworld,写个最简单的jsp就可以测试。
4.不要老想在windows下没有问题,linux下就能部署成功,注意操作系统的区别。
5.精简产出,如果你的包过大,则仔细检查是否有多余的包打进来,尽量把多余的包去除。