`
nesuk
  • 浏览: 168348 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

rmi.ConnectException: Connection refused to host: 127.0.0.1前因后果

阅读更多
又是Linux下RMI异常,不过这次是单网卡的情况,先看异常信息:
[appframe] 2012-10-09 15:20:59,217 - com.opensymphony.xwork2.DefaultActionInvocation -com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:383) -2603911 [http-8282-12] DEBUG  - Executing action method = haveDataContentView
org.springframework.remoting.RemoteConnectFailureException: Could not connect to remote service [rmi://192.168.2.74:7777/ViewService]; nested exception is java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is: 
	java.net.ConnectException: Connection refused
	at org.springframework.remoting.rmi.RmiClientInterceptorUtils.convertRmiAccessException(RmiClientInterceptorUtils.java:189)
	at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:347)
	at org.springframework.remoting.rmi.RmiClientInterceptor.invoke(RmiClientInterceptor.java:259)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
	at $Proxy65.viewDictContentHtml(Unknown Source)
	at com.plat.sap.action.SummaryPropertyDataAction.haveDataContentView(Unknown Source)


主要信息为:java.rmi.ConnectException: Connection refused to host: 127.0.0.1

经查,发现Server应用和Client应用都部署在单网卡的Linux上,且Server调Client端的RMI服务没问题,所以料到异常跟系统的域名或IP配置有关。通过Google异常,发现下面这篇文章,谢谢它最终指引我们解决了问题。现收藏如下:


java.rmi.ConnectException: Connection refused to host: 127.0.0.1异常主要根源是spring实现中,server端使用了主机名,linux在解析主机名时使用了与windows不同的逻辑。

在使用主机名时有两种说法:

说法一、 在server端返回的绑定对象中采用的是server主机名(hostname),写一个rmi客户端程序,你可能会收到如标题这样的异常。这个问题其实是由rmi服务器端程序造成的。客户端程序向服务端请求一个对象的时候,返回的stub对象里面包含了服务器的hostname,客户端的后续操作根据这个hostname来连接服务器端。要想知道这个hostname具体是什么值可以在服务器端bash中打入指令:
    hostname -i
如果返回的是127.0.0.1,那么你的客户端肯定会抛如标题的异常了。

解决这个问题有两个方式:
1) 修改/etc/hosts
找到127.0.0.1       hostxxxxx这样的字样。把127.0.0.1改成真实的,可供其他机器连接的ip。
这样客户端就能得到真实的ip了。
2) 在rmi服务器端程序启动脚本中加上两行,显式指定hostname。我的脚本:
  
 hostname=`hostname` 
java -cp $CLASSPATH -Djava.rmi.server.codebase=$codebase -Djava.security.policy=$PROJECT_HOME/se_server/conf/se_server.policy -
Djava.rmi.server.hostname=$hostname com.abc.server.StartServer > $PROJECT_HOME/se_server/logs/init.log 2>&1 &

不过该方式有个局限,其他机器肯定能识别ip,但是可能无法识别hostname。当然,你也可以直接写死这个hostname,比如:-Djava.rmi.server.hostname=xxx.xxx.xxx.xxx。 这样最省力,就是缺乏灵活性。


说法二、 返回的是根据主机名对应的ip

Linux系统使用/etc/hosts文件中localhost解析ip为127.0.0.1,当客户端向服务器Lookup时,服务端就会把解析出来的地址发给客户端,让客户端再根据这个地址去连接,客户端收到127.0.0.1这个地址,也使用/etc/hosts文件中localhost解析ip去连接,实际连接的是自己本身,当然也就不行了。

我把服务器的IP地址加到服务器的/etc/hosts文件中,并放在127.0.0.1之前,以让该服务能先解析到这个IP,从而正确解析出来机器名所对应的IP。


举例:
在服务端的 Naming.rebind("SectionWorkerManager", manager );没有指定ip,(这个语句在Windows下没问题)linux系统自己使用localhost解析为IP 127.0.0.1,当客户端向服务器Lookup时,服务端就会把解析出来的地址发给客户端,让客户端再根据这个地址去连接,客户端收到127.0.0.1这个地址去连接,实际连接的是自己本身,当然也就不行了。

更正办法:把Naming.rebind("SectionWorkerManager", manager);

改成Naming.rebind("rmi://10.1.5.xxx:1099/SectionWorkerManager", manager);,直接用IP地址(10.1.5.xxx:1099为服务器本身IP),这样就没问题了;

或者是用机器名,该服务器的名字为RHELTEST,把它加到服务器的hosts文件中,并放在127.0.0.1之前,以让该服务能正确解析出来机器名所对应的IP;要么用域名解析也行,这种方法比较适合大规模场合。

在Windows下能正常工作,在linux下却不行,这可能是操作系统解析localhost为ip时时的机制不一样引起的。

在redhat es5中测试,应该使用的是方法2。

不过两种方式都能解决该问题,采用哪种方式,根据服务器可做的修改来决定。
spring rmi对此的特别说明:

Note: RMI makes a best-effort attempt to obtain the fully qualified host name. If one cannot be determined, it will fall back and use the IP address. Depending on your network configuration, in some cases it will resolve the IP to the loopback address. To ensure that RMI will use the host name bound to the correct network interface, you should pass the java.rmi.server.hostname property to the JVM that will export the registry and/or the service using the "-D" JVM argument. For example: -Djava.rmi.server.hostname=myserver.com。

全文转载完毕。

以前还整理过一个双网卡下RMI配置的问题,mark一下,有空弄到网上来和大家分享。
分享到:
评论
1 楼 di1984HIT 2015-09-13  
学习了,写的不错。。。

相关推荐

    启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099的解决办法

     错误: 代理抛出异常错误: java.rmi.server.ExportException: Port already in use: 1099; nested exception is: java.net.BindException: Address already in use: JVM_Bind  这里说的是1099端口被其它进程占用...

    JMeter分布式原理,远程启动配置,jmeter在Linux上分布式压测环境搭建配置,命令行运行+问题集合,修改jvm值

    5 Server failed to start: java.rmi.RemoteException: Cannot start. localhost.localdomain is a loopback address.An error occurred: Cannot start. localhost.localdomain is a loopback address.

    jmeter在linux上运行报错问题解决.txt

    在linux上启动jmeter-server报错: ...Server failed to start: java.rmi.RemoteException: Cannot start. localhost is a loopback address. An error occurred: Cannot start. localhost is a loopback address.

    rmi.js:JavaScript的远程方法调用(RMI)

    RMI.js 想想JavaScript世界中的Java远程方法调用(RMI)。 RMI.js是一些JavaScript客户端代码和Node.js模块的组合,该模块可以实现远程方法的隐式调用。 开发人员可以使用本地,远程或两者的方法定义对象,然后在...

    java.util.concurrent.ExecutionException 问题解决方法

    错误信息中提到了`org.apache.catalina.LifecycleException`,这是一个与Tomcat容器生命周期有关的异常,表示在启动某个组件(如Engine、Host或Context)时失败。 首先,让我们深入理解`ExecutionException`: 1. ...

    JMX以RMI方式连接的场景示例

    JMX以RMI方式连接的场景示例 JMX(Java Management Extensions)是一种Java技术,用于管理和监控应用程序。JMX框架主要由三部分组成:MBean(Managed Bean)、Agent(代理)和Client(客户端)。在本场景中,我们将...

    RMI.rar_Java RMI_java.rmi_java.rmi.Remot_remote

    远程接口定义了可以在远程对象上执行的操作,它继承了`java.rmi.Remote`接口。这个接口不包含任何方法,但它是所有远程接口的基类,用来标记这些接口为远程可调用。远程对象是实现了远程接口的具体类,它实现了接口...

    java_rmi.rar_RMI java_java.rmi

    2. **实现远程接口**:然后,创建一个实现远程接口的类,该类通常需要继承自`java.rmi.Remote`接口,并且抛出`java.rmi.RemoteException`。在这个实现类中,你需要实现远程接口中的所有方法。 3. **创建并注册远程...

    RMI.rar_java programming

    1. 远程接口(Remote Interface):这是定义远程方法的接口,继承自java.rmi.Remote接口。远程接口中的每个方法都必须抛出java.rmi.RemoteException,因为远程调用可能因网络问题而失败。 2. 远程实现(Remote ...

    rmi.rar_remote

    标题"rmi.rar_remote"暗示了这个压缩包包含的是与Java RMI相关的程序或资源,可能是用于演示或实践RMI技术的示例代码。接下来,我们将深入探讨RMI的工作原理、组成部分以及如何实现它。 1. RMI工作原理: RMI的...

    RMI.zip_remote

    在"RMI.zip_remote"这个压缩包中,我们有四个文件,这些文件可能包含了实现RMI所需的基本组件: 1. **服务器端组件**:通常包含一个或多个实现了远程接口的类。远程接口定义了可以在远程对象上执行的方法。服务器端...

    java_rmi.zip

    接口需要使用`java.rmi.Remote`作为其父接口,并且所有方法必须抛出`java.rmi.RemoteException`。 3. **RMIServer**:实现了RMI接口的服务器端。服务器通过`java.rmi.registry.Registry`注册其服务,使客户端能够...

    rmi.rar_Java RMI_RMI java_RMI policy.all_rmi

    6. **部署和运行**:使用RMI时,需要将远程对象导出(`java.rmi.Naming.rebind()`),然后客户端可以通过`java.rmi.Naming.lookup()`查找并调用远程对象。在实际应用中,还需要配置JVM的RMI端口和其他网络参数。 在...

    RMI.zip_HTTP RMI_http视频_rmi视频教程

    【RMI.zip】是一个包含关于使用Remote Method Invocation (RMI)技术实现远程视频控制程序的资源包。RMI是Java平台提供的一种分布式计算机制,它允许一个Java对象调用另一个在不同JVM(Java Virtual Machine)上的...

    rmi.rar_Java RMI_RMI source code_java RMI simple_rmi

    1. **远程接口(Remote Interface)**:这是定义远程方法的Java接口,它标记为`java.rmi.Remote`的子接口。这些接口声明了可以在远程对象上执行的操作。 2. **远程实现(Remote Implementation)**:实现了远程接口...

    rmi.rar_rmi

    接口必须继承自`java.rmi.Remote`,并且它的方法必须抛出`java.rmi.RemoteException`。 2. **远程对象实现**:服务端需要实现上述接口,并创建其实例。这个实例就是远程对象,它负责处理客户端的调用请求。 3. **...

    RMI.rar_rmi

    这个接口必须继承自`java.rmi.Remote`,并且其方法抛出`java.rmi.RemoteException`。 - **远程对象(Remote Object)**:实现了远程接口的类实例,它驻留在服务器端,负责处理客户端的调用请求。 - **注册表...

Global site tag (gtag.js) - Google Analytics