วิธีเปิดใช้งาน JMX บน JVM สำหรับการเข้าถึงด้วย jconsole?
วิธีเปิดใช้งาน JMX บน JVM สำหรับการเข้าถึงด้วย jconsole?
คำตอบ:
เอกสารที่เกี่ยวข้องสามารถพบได้ที่นี่:
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
com.sun.management.jmxremote
true
(ขอบคุณ Sun!) เพื่อให้ชัดเจนโดยเฉพาะอย่างยิ่งผู้ที่คุ้นเคยน้อยกับ JMX nobs ฉันใช้: com.sun.management.jmxremote=true
Ref: docs.oracle.com/javase/8/docs/technotes/guides/management/ …
Dcom.sun.management.jmxremote.rmi.port=9011
และเปิดในไฟร์วอลล์ - ยังไม่สามารถเชื่อมต่อกับไฟร์วอลล์ที่กำลังทำงานอยู่ได้ ความคิดใด ๆ ฉันพลาดอะไรไปหรือเปล่า
การใช้งานใน 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...
Do not require SSL connection
อย่าลืมตรวจสอบช่องทำเครื่องหมาย หวังว่าจะช่วยให้คุณเชื่อมต่อได้
-Djava.rmi.server.hostname=localhost
-Dcom.sun.management.jmxremote.rmi.port=[...]
ก็เป็นกุญแจสำคัญในกรณีของการขุดอุโมงค์ JMX / RMI ผ่าน SSH หากไม่มีวัตถุระยะไกลก็สามารถเข้าถึงได้โดยใช้ public / main / ... IP ของเซิร์ฟเวอร์โดยใช้พอร์ตสุ่มซึ่งไม่สามารถส่งต่อได้อย่างง่ายดาย
-Djava.rmi.server.hostname=0.0.0.0
DOCKER_HOST_IP
ทุกที่ - ฉันเพิ่งใช้localhost
และส่งต่อพอร์ตเมื่อใช้ภาพนักเทียบท่านี้: -p 9998:9998, -p 9999:9999
ฯลฯ
หมายเหตุ Java 6 ในรูปแบบล่าสุดช่วยให้ jconsole สามารถแนบตัวเองเข้ากับกระบวนการทำงานได้แม้หลังจากที่เริ่มต้นโดยไม่ต้องใส่ JMX
หากสิ่งนั้นพร้อมใช้งานสำหรับคุณให้พิจารณา jvisualvm เนื่องจากมีข้อมูลมากมายเกี่ยวกับกระบวนการทำงานรวมถึง profiler
ฉันใช้ 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
บน 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)
รันโปรแกรม 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
แสดงข้อผิดพลาดหรือไม่หรือไม่เพียงแค่เชื่อมต่ออย่างเงียบ ๆ ?
พร้อมกับพารามิเตอร์บรรทัดคำสั่งด้านล่าง
-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 ซึ่งมีอยู่ในไฟล์โฮสต์
ก่อนอื่นคุณต้องตรวจสอบว่ากระบวนการจาวาของคุณทำงานอยู่กับพารามิเตอร์ 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
นี่มันเป็นพอร์ต
sudo lsof -i:1234
ไม่แสดงอะไรให้ฉัน
ขั้นตอนที่ 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 และคลิกที่ปุ่มเชื่อมต่อเพื่อเชื่อมต่อกับแอปพลิเคชันระยะไกล
คุณสามารถอ้างอิงลิงค์นี้สำหรับแอปพลิเคชันที่สมบูรณ์
ผมมีปัญหาตรงนี้และสร้างโครงการ GitHub สำหรับการทดสอบและการหาการตั้งค่าที่ถูกต้อง
มันมีการทำงานDockerfile
กับสคริปต์ที่สนับสนุนและง่ายdocker-compose.yml
สำหรับการทดสอบอย่างรวดเร็ว