Hello World! ソーシャルネットワーク事業部の、jyukutyoこと阪田です。

Firewall越しにVisualVMを接続しようとして少しハマったことを思い出し、記事にしよう!と思い立ちました。 VisualVMについてまとまっているWebページは多くあります。しかしリモート接続そしてFirewall越しとなるとなかなかまとまったものはありませんでした。お役に立てれば幸いです。

VisualVMとは

Java VisualVMとは「Java VisualVM は、Java Virtual Machine (JVM) 上で実行されている Java アプリケーションに関する詳細情報を表示したり、それらのアプリケーションのトラブルシューティングやプロファイリングを行なったりするためのビジュアルインタフェースを提供するツール」です(http://docs.oracle.com/javase/jp/7/technotes/guides/visualvm/)。

http://visualvm.java.net/からダウンロードして使用することもできますが、Java SE Version 6, Update 7から標準で付属しています。そのため、JAVA_HOME/binにパスが通っていれば「jvisualvm」というコマンドを実行するだけでVisualVMを起動できます。

VisualVMによって、リモートサーバ上で実行しているJavaアプリケーション(TomcatなどのサーブレットコンテナやOracle WebLogic Serverなどのアプリケーションサーバを含む)の情報を取得することができます。具体的にはCPU使用率やヒープ、Metaspace(PermGen)、クラスやスレッドなどの情報が取得できます。

Firewall越しにリモート接続

さて、VisualVMについてはこれぐらいにして、本題に入ります。

Firewallがあり特定のポートしか開いていない場合、オプションでポート番号を指定して接続できる…わけですが、すんなりいきません。

ここでは9999ポートが開いているとして、上記のようにポート番号を指定しました。しかしVisualVMでこのポート指定しても、接続できません。VisualVMはRMIでJVMに接続するのですが、実はRMIは2つのポートを利用するのです。

RMIレジストリポートとRMIサーバポート

RMIのクライアントは、まずRMIレジストリポートへ接続します。その後レジストリからスタブが取り出され、そのポートがサーバポートとして実際の通信に使われます。以前はそのポートは不明で、指定することができませんでした。指定できないためFirewall環境下ではRMI接続ができず、VisualVMは利用できません。しかしJava SE Version 7, Update 4以降は、オプションでRMIサーバポートを指定できるようになりました。

-Dcom.sun.management.jmxremote.rmi.port=9999

先ほどのオプションと合わせて、すべて指定すればFirewall越しにVisualVMに接続できます!

なお、com.sun.management.jmxremote.portcom.sun.management.jmxremote.rmi.portにまったく同じポートを指定できます。ポートが1つ開いてさえいれば、大丈夫です!

ただし、インターネット上に公開しているサーバならセキュリティ上の観点からcom.sun.management.jmxremote.authenticate=trueとし(またはこのオプションを指定せず、デフォルトのtrueとして使用し)、パスワードファイルを作成してcom.sun.management.jmxremote.password.fileオプションでパスワードファイルへのパスを指定しましょう。これで接続にユーザ名とパスワードが必要となります。

VisualVM起動!

さあ、今すぐjvisualvmコマンドを実行して、VisualVMを起動しましょう! スクリーンショット 2014-11-04 19.06.11

使い方は簡単です。画面上のボタンを押せば、CPU使用率やヒープ、Metaspace(PermGen)、クラスやスレッドなどの情報を数値やグラフを見ることができます。

参考URL

Tunneling JMX in the 7u4 JDK | Marcus Hirt http://hirt.se/blog/?p=289