質問
リモートマシンで実行されているJavaアプリケーションへのJMX接続を開こうとしています。
アプリケーションJVMは、次のオプションで構成されます。
- com.sun.management.jmxremote
- com.sun.management.jmxremote.port = 1088
- com.sun.management.jmxremote.authenticate = false
- com.sun.management.jmxremote.ssl = false
jconsoleまたはjvisualvmを使用して localhost:1088
を使用して接続できます。
しかし、リモートマシンから xxx.xxx.xxx.xxx:1088
を使用して接続することはできません。
サーバー間またはOS上にファイアウォールはありません。しかし、この可能性を排除するために、 telnet xxx.xxx.xxx.xxx 1088
とコンソール画面が空白になると接続すると思います。
両方のサーバーはWindows Server 2008 x64です。 64ビットJVMと32ビットで試してみましたが、どちらも動作しません。
解決
Linuxの場合、問題は localhostがループバックインターフェースであるため、アプリケーションをネットワークインターフェースにバインドする必要があります。
netstatを使用して、予想されるネットワークインターフェイスにバインドされていないことを確認できます。
システム変数 java.rmi.server.hostname =" YOUR_IP"
を環境変数として使用するか、
java -Djava.rmi.server.hostname=YOUR_IP YOUR_APP
他のヒント
ローカルホストの外部からJMXを機能させるために1日以上費やしました。 SUN / Oracleは、これに関する適切なドキュメントを提供できなかったようです。
次のコマンドが実際のIPまたはHOSTNAMEを返すことを確認してください。 127.0.0.1、127.0.1.1またはlocalhostのような何かを返す場合、それは機能せず、 / etc / hosts
ファイルを更新する必要があります。
hostname -i
外部からでもJMXを有効にするために必要なコマンドは次のとおりです
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=1100
-Djava.rmi.server.hostname=myserver.example.com
想定どおり、myserver.example.comは hostname -i
が返すものと一致する必要があります。
明らかに、ファイアウォールによってブロックされないことを確認する必要がありますが、これはあなたの問題ではないことはほぼ確実です。問題は文書化されていない最後のパラメータです。
TomcatとJava 8でのテストでは、JVMはJMXに指定されたポートに加えて一時ポートを開いていました。次のコードで修正されました。 JMXクライアント(たとえば、 VisualVM が接続していない問題が発生している場合は、試してみてください。
-Dcom.sun.management.jmxremote.port=8989
-Dcom.sun.management.jmxremote.rmi.port=8989
http://blogs.oracle.com/jmxetc/entry/troubleshooting_connection_problems_in_jconsole
NATの背後にあるサーバーにアクセスしようとしている場合、ほとんどの場合、オプションでサーバーを起動する必要があります
-Djava.rmi.server.hostname=<public/NAT address>
クライアントに送信されるRMIスタブにサーバーのパブリックアドレスが含まれ、外部からクライアントが到達できるようにします。
終了の引用が早すぎるということです。最後のパラメーターの後でなければなりません。
このトリックは私のために働いた。
興味深いことに気付きました。次のコマンドラインを使用してアプリケーションを起動すると、
java -Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
jconsoleを使用してリモートマシンからこのポートに接続しようとすると、TCP接続は成功し、リモートjconsoleと、MBeanがデプロイされているローカルjmxエージェント間でデータが交換され、jconsoleは接続エラーメッセージを表示します。 Wiresharkのキャプチャを実行したところ、エージェントとjconsoleの両方からのデータ交換が表示されています。
したがって、これはネットワークの問題ではありません。java.rmi.server.hostnameシステムプロパティの有無にかかわらずnetstat -anを実行すると、次のバインディングがあります。
TCP 0.0.0.0:9999 0.0.0.0:0 LISTENING
TCP [::]:9999 [::]:0 LISTENING
どちらの場合も、ポート9999で作成されたソケットは、任意のアドレスの任意のホストからの接続を受け入れます。
このシステムプロパティのコンテンツは接続のどこかで使用され、jconsoleとの通信にエージェントが使用する実際のIPアドレスと比較されると思います。そして、それらのアドレスが一致しない場合、接続は失敗します。
jconsoleを使用して同じホストから接続している間は、実際の物理リモートホストからのみこの問題は発生しませんでした。したがって、このチェックは「外部」から接続が来ているときにのみ行われると思います。
どうもありがとう、次のように動作します:
java -Djava.rmi.server.hostname = xxx.xxx.xxx.xxx -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote .ssl = false -Dcom.sun.management.jmxremote.authenticate = false -Dcom.sun.management.jmxremote.port = 25000 -jar myjar .jar
私にとっては、ホスト名がループバックインターフェイスではなくIPを指すように/ etc / hostsを設定し、アプリケーションを再起動することでした。
cat / etc / hosts
127.0.0.1 localhost.localdomain localhost
192.168.0.1 myservername
これは私の構成です:
-Dcom.sun.management.jmxremote.port=1617
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
このスレッドはかなり古いものですが、非常に役立つ追加オプションがあります。こちらをご覧ください: https://realjenius.com/2012/11/ 21 / java7-jmx-tunneling-freedom /
-Dcom.sun.management.jmxremote.rmi.port = 1099
同じ問題があり、ローカルホスト名に一致するホスト名を0.0.0.0に変更します。それを行った後、動作するようです。
JMXリモートを有効にするには、JAVAコマンドとともに以下のVMパラメーターを渡します。
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=453
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=myDomain.in
3000以上のポートを使用してみてください。