Bagaimana cara mengaktifkan JMX pada JVM saya untuk akses dengan jconsole?

223

Bagaimana cara mengaktifkan JMX pada JVM untuk akses dengan jconsole?

Mauli
sumber
32
itu allowd, dan benar-benar hanya pengingat bagi saya, karena saya selalu lupa di mana untuk menyalin parameter dari dan sekarang saya tahu di mana saya merasa :-)
Mauli
20
Stack Exchange selalu secara eksplisit mendorong pengguna untuk menjawab pertanyaan mereka sendiri, lihat di sini: stackoverflow.com/help/self-answer
Tim Büthe
11
Lebih dari sekali saya telah mencari SO untuk sesuatu dan menemukan pertanyaan dijawab ... sendiri. Dan salah satu dari mereka diminta oleh saya juga. Inilah sebabnya mengapa baik untuk memasukkan jawaban Anda sendiri. Juga, pikirkan semua orang lain yang mungkin mengalami masalah Anda, jika Anda menjawab pertanyaan Anda, Anda akan membantu mereka juga.
Mike Miller
2
Dokumen terbaru untuk Java 8 ada di sini
Andrew Johnston
@Mauren: Bisakah Anda memberikan referensi ke pertanyaan tertutup yang Anda jawab sendiri? Mungkin layak untuk dibahas di Meta.
kevinarpe

Jawaban:

290

Dokumentasi yang relevan dapat ditemukan di sini:

http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html

Mulai program Anda dengan parameter berikut:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.rmi.port=9010
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

Misalnya seperti ini:

java -Dcom.sun.management.jmxremote \
  -Dcom.sun.management.jmxremote.port=9010 \
  -Dcom.sun.management.jmxremote.local.only=false \
  -Dcom.sun.management.jmxremote.authenticate=false \
  -Dcom.sun.management.jmxremote.ssl=false \
  -jar Notepad.jar

-Dcom.sun.management.jmxremote.local.only=falsetidak harus diperlukan tetapi tanpa itu, itu tidak berfungsi di Ubuntu. Kesalahannya akan seperti ini:

01 Oct 2008 2:16:22 PM sun.rmi.transport. customer .TCPTransport$AcceptLoop executeAcceptLoop
WARNING: RMI TCP Accept-0: accept loop for ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=37278] throws
java.io.IOException: The server sockets created using the LocalRMIServerSocketFactory only accept connections from clients running on the host where the RMI remote objects have been exported.
    at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:89)
    at sun.rmi.transport. customer .TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:387)
    at sun.rmi.transport. customer .TCPTransport$AcceptLoop.run(TCPTransport.java:359)
    at java.lang.Thread.run(Thread.java:636)

lihat http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6754672

Juga berhati-hatilah dengan-Dcom.sun.management.jmxremote.authenticate=false yang membuat akses tersedia bagi siapa saja, tetapi jika Anda hanya menggunakannya untuk melacak JVM pada mesin lokal Anda, itu tidak masalah.

Perbarui :

Dalam beberapa kasus saya tidak dapat menjangkau server. Ini kemudian diperbaiki jika saya mengatur parameter ini juga:-Djava.rmi.server.hostname=127.0.0.1

Mauli
sumber
9
The -Dcom.sun.management.jmxremote.local.only = false juga diperlukan di Centos
LenW
1
Nit pick: Aneh bagi saya yang com.sun.management.jmxremotememiliki nilai default sebagai true. (Terima kasih Sun!) Untuk menjadi sangat jelas, terutama bagi mereka yang tidak terlalu mengenal JMX, saya menggunakan: com.sun.management.jmxremote=trueRef: docs.oracle.com/javase/8/docs/technotes/guides/management/…
kevinarpe
1
"-Djava.rmi.server.hostname" bekerja seperti pesona bagi saya!
Orhun D.
1
mengatur nama host ke localhost sangat penting jika Anda mencoba untuk menghubungkan ke server jauh melalui terowongan SSH, yang merupakan kasus yang sangat umum.
Nikhil Owalekar
1
Itu hanya berfungsi jika saya menonaktifkan firewall di server. Saya membuka port 9010 / tcp dalam contoh ini tentu saja, saya juga mencoba menambah Dcom.sun.management.jmxremote.rmi.port=9011dan membuka di firewall - masih tidak dapat terhubung dengan firewall yang sedang menyala. Adakah pikiran? Apakah saya melewatkan sesuatu?
Carmageddon
70

Menjalankan dalam wadah Docker memperkenalkan banyak masalah tambahan untuk menghubungkan jadi mudah-mudahan ini membantu seseorang. Saya akhirnya perlu menambahkan opsi berikut yang akan saya jelaskan di bawah:

-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=${DOCKER_HOST_IP}
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.rmi.port=9998

DOCKER_HOST_IP

Tidak seperti menggunakan jconsole secara lokal, Anda harus mengiklankan IP yang berbeda dari yang mungkin Anda lihat dari dalam wadah. Anda harus mengganti ${DOCKER_HOST_IP}dengan IP (Nama DNS) yang dapat diatasi secara eksternal dari host Docker Anda.

JMX Remote & RMI Ports

Sepertinya JMX juga memerlukan akses ke antarmuka manajemen jarak jauh ( jstat ) yang menggunakan port berbeda untuk mentransfer beberapa data saat menengahi koneksi. Saya tidak melihat di mana pun segera jelas dalam jconsolemenetapkan nilai ini. Dalam artikel yang ditautkan prosesnya adalah:

  • Coba dan hubungkan dari jconsoledengan logging diaktifkan
  • Gagal
  • Cari tahu port mana yang jconsoleingin digunakan
  • Gunakan iptables/ firewallaturan seperlunya untuk memungkinkan port terhubung

Sementara itu berhasil, itu tentu saja bukan solusi yang dapat diautomatiskan. Saya memilih untuk upgrade dari jconsole ke VisualVM karena memungkinkan Anda untuk secara eksplisit menentukan port yang jstatdsedang berjalan. Dalam VisualVM, tambahkan Host Remote Baru dan perbarui dengan nilai-nilai yang berkorelasi dengan yang ditentukan di atas:

Tambahkan Host Jarak Jauh

Kemudian klik kanan Remote Host Connection dan Add JMX Connection...

Tambahkan Koneksi JMX

Jangan lupa untuk mencentang kotak centang Do not require SSL connection. Semoga itu memungkinkan Anda terhubung.

Joel B
sumber
-Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote.rmi.port=[...]juga merupakan kunci dalam hal tunneling JMX / RMI melalui SSH. Tanpa itu, objek jarak jauh diakses menggunakan IP publik / utama / ... dari server menggunakan beberapa port acak, yang tidak dapat diteruskan dengan mudah.
Thorsten Schöning
1
Saya dapat mengonfirmasi bahwa Anda benar-benar perlu menggunakan IP eksternal untuk wadah. Misalnya tidak bekerja dengan-Djava.rmi.server.hostname=0.0.0.0
raisercostin
Saya tidak perlu menggunakan di DOCKER_HOST_IPmana saja - Saya hanya menggunakan localhostdan meneruskan port ketika menjalankan gambar buruh pelabuhan: -p 9998:9998, -p 9999:9999dll.
Barney
9

Catatan, Java 6 dalam inkarnasi terbaru memungkinkan jconsole untuk melampirkan dirinya ke proses yang berjalan bahkan setelah dimulai tanpa mantra JMX.

Jika itu tersedia untuk Anda, pertimbangkan juga jvisualvm karena menyediakan banyak informasi tentang proses yang berjalan, termasuk profiler.

Thorbjørn Ravn Andersen
sumber
3
Ini hanya berfungsi jika Anda menjalankan jconsole pada host yang sama dengan JVM yang Anda coba pantau.
Gray
1
@ Thorbjorn Jika saya memulai program java saya tanpa parameter dan mencoba untuk terhubung dengan jconsole, saya lihat di program saya dalam daftar tetapi ketika saya mencoba untuk menghubungkannya gagal. Saya pikir itu karena kurangnya sertifikat SSL. Saya hanya ingin melihat demo maka saya harus menggunakan parameter yang ditentukan dalam jawaban oleh user3013578 dan itu berhasil untuk saya (JDK 1.7, Windows 8.1, 64 bit).
Kapten Jack Sparrow
2
API attach membutuhkan jconsole untuk memiliki JVM 32/64 bit yang sama dengan program yang diluncurkan pada beberapa platform.
Thorbjørn Ravn Andersen
1
Apakah mungkin untuk menonaktifkan perilaku ini?
kevinarpe
7

Saya menggunakan WS WS 7.0

JVM saya perlu semua argumen berikut untuk dipantau di JConsole

    -Djavax.management.builder.initial= 
    -Dcom.sun.management.jmxremote 
    -Dcom.sun.management.jmxremote.port=8855 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.ssl=false
pengguna3013578
sumber
Ya jawaban Anda bekerja untuk saya (JDK 1.7, windows 8.1 64 bit)
Kapten Jack Sparrow
6

Di Linux, saya menggunakan params berikut:

-Djavax.management.builder.initial= 
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=9010 
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false

dan saya juga mengedit /etc/hostsagar nama host memutuskan ke alamat host (192.168.0.x) daripada alamat loopback (127.0.0.1)

alex.pulver
sumber
2

Jalankan aplikasi java Anda dengan parameter baris perintah berikut:

-Dcom.sun.management.jmxremote.port=8855
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

Penting untuk menggunakan -Dcom.sun.management.jmxremote.ssl = parameter salah jika Anda tidak ingin mengatur sertifikat digital pada host jmx.

Jika Anda memulai aplikasi pada mesin yang memiliki alamat IP 192.168.0.1 , buka jconsole , masukkan 192.168.0.1:8855 di bidang Proses Jarak Jauh , dan klik Connect .

Wasif
sumber
Apa perilaku yang diharapkan jika Anda lupa -Dcom.sun.management.jmxremote.ssl=false? Haruskah jconsolemenunjukkan kesalahan, atau apakah hanya diam-diam gagal terhubung?
amacleod
2

bersama dengan parameter baris perintah di bawah ini,

-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

Terkadang di server linux, koneksi IMX tidak berhasil. itu karena, di cloud linux host, di / etc / hosts sehingga nama host diselesaikan ke alamat host.

cara terbaik untuk memperbaikinya adalah, ping server linux tertentu dari mesin lain di jaringan dan gunakan alamat IP host tersebut di

-Djava.rmi.server.hostname=IP address that obtained when you ping that linux server.

Tapi jangan pernah mengandalkan ipaddress yang Anda dapatkan dari server linux menggunakan ifconfig.me. ip yang Anda dapatkan di sana adalah salah satu yang ada di file host.

Phani Kumar
sumber
1

Pertama, Anda perlu memeriksa apakah proses java Anda sudah berjalan dengan parameter JMX. Melakukan hal ini:

ps -ef | grep java

Periksa proses java Anda, Anda perlu memonitor. Jika Anda dapat melihat jmx rmi parameter Djmx.rmi.registry.port = xxxx kemudian gunakan port yang disebutkan di sini di java visualvm Anda untuk menghubungkannya dari jarak jauh di bawah koneksi jmx.

Jika tidak berjalan melalui port rm jmx maka Anda perlu menjalankan proses java Anda dengan parameter yang disebutkan di bawah ini:

-Djmx.rmi.registry.port=1234 -Djmx.rmi.port=1235 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

Catatan: nomor port didasarkan pada pilihan Anda.

Sekarang Anda dapat menggunakan port ini untuk koneksi jmx. Ini dia port 1234.

Abhay S
sumber
Apakah Anda dapat melihat port 1234 yang digunakan oleh jmx setelah Anda menjalankan ini? sudo lsof -i:1234tidak menunjukkan apa pun untuk saya
Gorgon_Union
1

Langkah 1: Jalankan aplikasi menggunakan parameter berikut.

-Dcom.sun.management.jmxremote.port=9999 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false

Argumen di atas mengikat aplikasi ke port 9999.

Langkah 2: Luncurkan jconsole dengan menjalankan perintah jconsole di command prompt atau terminal.

Pilih 'Remote Process:' dan masukkan url sebagai {IP_Address}: 9999 dan klik tombol Connect untuk menghubungkan ke aplikasi jarak jauh.

Anda dapat merujuk tautan ini untuk aplikasi lengkap.

Hari Krishna
sumber