วิธีเปิดใช้งาน JMX บน JVM ของฉันเพื่อเข้าถึงด้วย jconsole?


223

วิธีเปิดใช้งาน JMX บน JVM สำหรับการเข้าถึงด้วย jconsole?


32
มันเป็น allowd และที่จริงมันก็เป็นเพียงการแจ้งเตือนสำหรับฉันเพราะฉันมักจะลืมที่จะคัดลอกพารามิเตอร์จากและตอนนี้ฉันรู้ว่าฉันคิดว่ามัน :-)
mauli

20
การแลกเปลี่ยนแบบสแต็กสนับสนุนให้ผู้ใช้ตอบคำถามของตัวเองอย่างชัดเจนดูที่นี่: stackoverflow.com/help/self-answer
Tim Büthe

11
มากกว่าหนึ่งครั้งที่ฉันค้นหาบางสิ่งบางอย่างและพบคำถามที่ตอบ ... ด้วยตัวเอง และฉันก็ถามหนึ่งในนั้นเช่นกัน นี่คือเหตุผลว่าทำไมจึงเป็นการดีที่จะตอบคำถามของคุณเองนอกจากนี้ให้คิดถึงคนอื่น ๆ ที่อาจประสบปัญหาของคุณหากคุณตอบคำถามของคุณคุณจะช่วยเหลือพวกเขาด้วย
Mike Miller

2
อัปเดตเอกสารสำหรับ Java 8 อยู่ที่นี่แล้ว
Andrew Johnston

@Mauren: คุณสามารถให้การอ้างอิงถึงคำถามปิดของคุณที่คุณตอบตัวเอง? มันอาจคุ้มค่าที่จะพูดคุยกับ Meta
kevinarpe

คำตอบ:


290

เอกสารที่เกี่ยวข้องสามารถพบได้ที่นี่:

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

เริ่มโปรแกรมของคุณด้วยพารามิเตอร์ต่อไปนี้:

-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

ตัวอย่างเช่นนี้:

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=falseไม่จำเป็นต้องมี แต่ถ้าขาดมันก็ไม่สามารถใช้งานได้บน Ubuntu ข้อผิดพลาดจะเป็นดังนี้:

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)

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

ระวัง-Dcom.sun.management.jmxremote.authenticate=falseด้วยว่าการเข้าถึงแบบใดที่ใคร ๆ ก็ทำได้ แต่ถ้าคุณใช้เพื่อติดตาม JVM บนเครื่องของคุณก็ไม่สำคัญ

อัปเดต :

ในบางกรณีฉันไม่สามารถเข้าถึงเซิร์ฟเวอร์ นี่คือการแก้ไขแล้วถ้าฉันตั้งค่าพารามิเตอร์นี้เช่นกัน:-Djava.rmi.server.hostname=127.0.0.1


9
-Dcom.sun.management.jmxremote.local.only = false เป็นสิ่งจำเป็นใน Centos ตอนนี้ได้เป็นอย่างดี
LenW

1
nit เลือก: มันแปลกกับผมว่ามีค่าเริ่มต้นเป็นcom.sun.management.jmxremote true(ขอบคุณ Sun!) เพื่อให้ชัดเจนโดยเฉพาะอย่างยิ่งผู้ที่คุ้นเคยน้อยกับ JMX nobs ฉันใช้: com.sun.management.jmxremote=trueRef: docs.oracle.com/javase/8/docs/technotes/guides/management/ …
kevinarpe

1
"-Djava.rmi.server.hostname" ได้ผลเช่นเดียวกับฉัน!
Orhun D.

1
การตั้งค่าชื่อโฮสต์เป็น localhost มีความสำคัญมากหากคุณพยายามเชื่อมต่อกับเซิร์ฟเวอร์ระยะไกลผ่านช่องทาง SSH ซึ่งเป็นกรณีทั่วไป
Nikhil Owalekar

1
สิ่งนี้ใช้ได้เฉพาะเมื่อฉันปิดการใช้งานไฟร์วอลล์บนเซิร์ฟเวอร์ ฉันเปิดพอร์ต 9010 / tcp ในตัวอย่างนี้แน่นอนฉันพยายามเพิ่มDcom.sun.management.jmxremote.rmi.port=9011และเปิดในไฟร์วอลล์ - ยังไม่สามารถเชื่อมต่อกับไฟร์วอลล์ที่กำลังทำงานอยู่ได้ ความคิดใด ๆ ฉันพลาดอะไรไปหรือเปล่า
Carmageddon

70

การใช้งานใน Docker container นำเสนอปัญหาเพิ่มเติมมากมายสำหรับการเชื่อมต่อดังนั้นหวังว่านี่จะช่วยให้ใครบางคน ฉันจำเป็นต้องเพิ่มตัวเลือกต่อไปนี้ซึ่งฉันจะอธิบายด้านล่าง:

-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

แตกต่างจากการใช้ jconsole ในพื้นที่คุณต้องโฆษณา IP ที่แตกต่างจากที่คุณเคยเห็นจากในคอนเทนเนอร์ คุณจะต้องแทนที่${DOCKER_HOST_IP}ด้วย IP (ชื่อ DNS) ที่แก้ไขได้ภายนอกของโฮสต์ Docker ของคุณ

รีโมต JMX & พอร์ต RMI

ดูเหมือนว่า JMX ยังต้องการการเข้าถึงอินเทอร์เฟซการจัดการระยะไกล ( jstat ) ที่ใช้พอร์ตอื่นเพื่อถ่ายโอนข้อมูลบางอย่างเมื่อทำการเชื่อมต่อ ฉันไม่เห็นที่ใดก็ได้ในทันทีjconsoleเพื่อกำหนดค่านี้ ในบทความที่เชื่อมโยงกระบวนการคือ:

  • ลองและเชื่อมต่อจากjconsoleด้วยการเปิดใช้งานการบันทึก
  • ล้มเหลว
  • กำหนดพอร์ตที่jconsoleพยายามใช้
  • ใช้iptables/ firewallกฎตามที่จำเป็นเพื่ออนุญาตให้พอร์ตนั้นเชื่อมต่อ

ในขณะที่ใช้งานได้แน่นอนไม่ใช่วิธีแก้ปัญหาอัตโนมัติ ฉันเลือกที่จะอัพเกรดจาก jconsole เป็นVisualVMเพราะให้คุณระบุพอร์ตที่jstatdใช้งานได้อย่างชัดเจน ใน VisualVM เพิ่ม New Remote Host และอัพเดทด้วยค่าที่สัมพันธ์กับรายการที่ระบุด้านบน:

เพิ่มโฮสต์ระยะไกล

จากนั้นคลิกขวาที่ Remote Host Connection ใหม่และ Add JMX Connection...

เพิ่มการเชื่อมต่อ JMX

Do not require SSL connectionอย่าลืมตรวจสอบช่องทำเครื่องหมาย หวังว่าจะช่วยให้คุณเชื่อมต่อได้


-Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote.rmi.port=[...]ก็เป็นกุญแจสำคัญในกรณีของการขุดอุโมงค์ JMX / RMI ผ่าน SSH หากไม่มีวัตถุระยะไกลก็สามารถเข้าถึงได้โดยใช้ public / main / ... IP ของเซิร์ฟเวอร์โดยใช้พอร์ตสุ่มซึ่งไม่สามารถส่งต่อได้อย่างง่ายดาย
Thorsten Schöning

1
ฉันสามารถยืนยันได้ว่าคุณจำเป็นต้องใช้ภายนอกกับ IP คอนเทนเนอร์ ตัวอย่างเช่นมันใช้ไม่ได้กับ-Djava.rmi.server.hostname=0.0.0.0
raisercostin

ผมไม่จำเป็นต้องใช้DOCKER_HOST_IPทุกที่ - ฉันเพิ่งใช้localhostและส่งต่อพอร์ตเมื่อใช้ภาพนักเทียบท่านี้: -p 9998:9998, -p 9999:9999ฯลฯ
บาร์นีย์

9

หมายเหตุ Java 6 ในรูปแบบล่าสุดช่วยให้ jconsole สามารถแนบตัวเองเข้ากับกระบวนการทำงานได้แม้หลังจากที่เริ่มต้นโดยไม่ต้องใส่ JMX

หากสิ่งนั้นพร้อมใช้งานสำหรับคุณให้พิจารณา jvisualvm เนื่องจากมีข้อมูลมากมายเกี่ยวกับกระบวนการทำงานรวมถึง profiler


3
ใช้งานได้เฉพาะถ้าคุณใช้ jconsole บนโฮสต์เดียวกันกับ JVM ที่คุณพยายามตรวจสอบ
สีเทา

1
@ Thorbjorn หากฉันเริ่มโปรแกรม Java โดยไม่มีพารามิเตอร์ใด ๆ และพยายามเชื่อมต่อกับ jconsole ฉันเห็นในโปรแกรมของฉันในรายการ แต่เมื่อฉันพยายามเชื่อมต่อมันล้มเหลว ฉันคิดว่าเป็นเพราะขาดใบรับรอง SSL ฉันแค่อยากเห็นการสาธิตดังนั้นฉันต้องใช้พารามิเตอร์ที่ระบุในคำตอบโดย user3013578 และมันใช้งานได้สำหรับฉัน (JDK 1.7, Windows 8.1, 64 บิต)
กัปตัน Jack Sparrow

2
API ที่แนบมานั้นต้องการ jconsole เพื่อให้มี JVM 32/64 บิตเหมือนกันกับโปรแกรมที่เรียกใช้ในบางแพลตฟอร์ม
Thorbjørn Ravn Andersen

1
เป็นไปได้หรือไม่ที่จะปิดใช้งานพฤติกรรมนี้
kevinarpe

7

ฉันใช้ WAS ND 7.0

JVM ของฉันต้องการอาร์กิวเมนต์ทั้งหมดต่อไปนี้เพื่อตรวจสอบใน 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

ใช่คำตอบของคุณใช้ได้สำหรับฉัน (JDK 1.7, windows 8.1 64 บิต)
Captain Jack Sparrow

6

บน Linux ฉันใช้พารามิเตอร์ต่อไปนี้:

-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

และฉันก็แก้ไข/etc/hostsเพื่อให้ชื่อโฮสต์แก้ไขเป็นที่อยู่โฮสต์ (192.168.0.x) มากกว่าที่อยู่ย้อนกลับ (127.0.0.1)


2

รันโปรแกรม Java ของคุณด้วยพารามิเตอร์บรรทัดคำสั่งต่อไปนี้:

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

เป็นสิ่งสำคัญที่จะต้องใช้พารามิเตอร์-Dcom.sun.management.jmxremote.ssl = falseถ้าคุณไม่ต้องการตั้งค่าใบรับรองดิจิทัลบนโฮสต์ jmx

หากคุณเริ่มต้นใบสมัครของคุณบนเครื่องที่มีอยู่ IP 192.168.0.1เปิดjconsoleใส่192.168.0.1:8855ในกระบวนการระยะไกลฟิลด์และคลิกConnect


พฤติกรรมที่คาดหวังถ้าคุณลืมคืออะไร-Dcom.sun.management.jmxremote.ssl=false? ควรjconsoleแสดงข้อผิดพลาดหรือไม่หรือไม่เพียงแค่เชื่อมต่ออย่างเงียบ ๆ ?
amacleod

2

พร้อมกับพารามิเตอร์บรรทัดคำสั่งด้านล่าง

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

บางครั้งในเซิร์ฟเวอร์ linux การเชื่อมต่อ imx ไม่สำเร็จ นั่นเป็นเพราะใน cloud linux host ใน / etc / hosts เพื่อให้ชื่อโฮสต์แก้ไขเป็นที่อยู่โฮสต์

วิธีที่ดีที่สุดในการแก้ไขคือการ ping เซิร์ฟเวอร์ linux เฉพาะจากเครื่องอื่นในเครือข่ายและใช้ที่อยู่ IP ของโฮสต์ใน

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

แต่อย่าพึ่งพา ipaddress ที่คุณได้รับจากเซิร์ฟเวอร์ linux โดยใช้ ifconfig.me ip ที่คุณได้รับมาพร้อมกับ masked ซึ่งมีอยู่ในไฟล์โฮสต์


1

ก่อนอื่นคุณต้องตรวจสอบว่ากระบวนการจาวาของคุณทำงานอยู่กับพารามิเตอร์ JMX หรือไม่ ทำเช่นนี้:

ps -ef | grep java

ตรวจสอบกระบวนการ Java ของคุณที่คุณต้องตรวจสอบ หากคุณสามารถดูพารามิเตอร์ jmx rmi Djmx.rmi.registry.port = xxxx ให้ใช้พอร์ตที่กล่าวถึงที่นี่ใน java visualvm ของคุณเพื่อเชื่อมต่อจากระยะไกลภายใต้การเชื่อมต่อ jmx

หากไม่ได้ทำงานผ่านพอร์ต jmx rmi คุณจะต้องเรียกใช้กระบวนการจาวาของคุณโดยใช้พารามิเตอร์ที่ระบุไว้ด้านล่าง

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

หมายเหตุ: หมายเลขพอร์ตขึ้นอยู่กับการเลือกของคุณ

ตอนนี้คุณสามารถใช้พอร์ตนี้สำหรับ jmx coneection 1234นี่มันเป็นพอร์ต


คุณควรจะเห็นพอร์ต 1234 ที่ใช้งานโดย jmx เมื่อคุณเรียกใช้สิ่งนี้? sudo lsof -i:1234ไม่แสดงอะไรให้ฉัน
Gorgon_Union

1

ขั้นตอนที่ 1:เรียกใช้แอปพลิเคชันโดยใช้พารามิเตอร์ต่อไปนี้

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

อาร์กิวเมนต์ด้านบนเชื่อมโยงแอปพลิเคชันกับพอร์ต 9999

ขั้นตอนที่ 2:เรียกใช้ jconsole โดยดำเนินการคำสั่ง jconsole ใน command prompt หรือเทอร์มินัล

เลือก 'Remote Process:' และป้อน URL เป็น {IP_Address}: 9999 และคลิกที่ปุ่มเชื่อมต่อเพื่อเชื่อมต่อกับแอปพลิเคชันระยะไกล

คุณสามารถอ้างอิงลิงค์นี้สำหรับแอปพลิเคชันที่สมบูรณ์


0

ผมมีปัญหาตรงนี้และสร้างโครงการ GitHub สำหรับการทดสอบและการหาการตั้งค่าที่ถูกต้อง

มันมีการทำงานDockerfileกับสคริปต์ที่สนับสนุนและง่ายdocker-compose.ymlสำหรับการทดสอบอย่างรวดเร็ว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.