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

4626 ワード

またLinuxでRMI異常ですが、今回はシングルNICの場合、まず異常情報を見ます.
[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
調べたところ、サーバーアプリケーションとClientアプリケーションはいずれもシングルNICのLinux上に配置されており、サーバー調Client側のRMIサービスは問題ないことが分かったので、異常はシステムのドメイン名やIP構成と関係があると予想された.Googleの異常を通じて、次の文章を発見しました.最終的に問題を解決してくれてありがとう.コレクションは以下の通りです.
java.rmi.ConnectException:Connection refused to host:127.0.0.1異常の主な原因はspring実装で、server側はホスト名を使用し、linuxはホスト名を解析する際にwindowsとは異なる論理を使用した.
ホスト名を使用する場合は、次の2つの言い方があります.
説一、server側が返すバインドオブジェクトにはserverホスト名(hostname)が採用されており、rmiクライアントプログラムを書くと、タイトルのような異常が受信される可能性があります.この問題はrmiサーバ側プログラムによるものである.クライアントプログラムがサービス側にオブジェクトを要求すると,返されるstubオブジェクトにはサーバのhostnameが含まれており,クライアントの後続操作はこのhostnameに基づいてサーバ側に接続される.このhostnameの具体的な値がサーバ側bashにコマンドを入力できるかどうかを知るには、次の手順に従います.
    hostname -i
127.0.0.1を返すと、クライアントはタイトルの異常のように投げられるに違いありません.
この問題を解決するには2つの方法があります.
1)修正/etc/hosts
127.0.0.1 hostxxxxxという文字が見つかりました.127.0.0.1をリアルに変更し、他のマシンに接続できるip.
これでクライアントは実際のipを得ることができます.
2)rmiサーバ側プログラム起動スクリプトに2行を加え、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. このように最も省力的なのは、柔軟性に欠けていることだ.
言い方2、返されるのはホスト名に応じた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が指定されていません.linuxシステムはlocalhostを使用してIP 127.0.0.1に解析します.クライアントがサーバにLookupすると、サービス側は解析したアドレスをクライアントに送り、クライアントにこのアドレスに基づいて接続させます.クライアント側は127.0.0.1というアドレスを受け取って接続します.実際に接続しているのは自分自身です.もちろんだめです.
修正方法:Naming.rebind("SectionWorkerManager", manager);
名前を変更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 es 5でテストするには、方法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.
全文転載完了.
以前はまた1つの2つのネットカードの下でRMIの配置の問題を整理したことがあって、markはすぐに、暇があってネット上でみんなと分かち合います.