Làm cách nào để kích hoạt JMX trên JVM của tôi để truy cập bằng jconsole?


223

Làm cách nào để kích hoạt JMX trên JVM để truy cập bằng jconsole?


32
nó là cho phép, và thực sự nó chỉ là một lời nhắc nhở cho tôi, bởi vì tôi luôn quên nơi để sao chép các tham số từ đó và bây giờ tôi biết tôi tìm thấy nó ở đâu :-)
Mauli

20
Stack Exchange luôn khuyến khích người dùng trả lời các câu hỏi của riêng họ một cách rõ ràng, xem tại đây: stackoverflow.com/help/elf-answer
Tim Büthe

11
Hơn một lần tôi đã tìm kiếm SO một cái gì đó và tìm thấy một câu hỏi được trả lời ... một mình. Và một trong số đó cũng được tôi hỏi. Đây là lý do tại sao nên đưa câu trả lời của riêng bạn vào. Ngoài ra, hãy nghĩ đến tất cả những người khác có thể đã gặp phải vấn đề của bạn, nếu bạn trả lời câu hỏi của mình, bạn cũng sẽ giúp họ.
Mike Miller

2
Tài liệu cập nhật cho Java 8 có tại đây
Andrew Johnston

@Mauren: Bạn có thể cung cấp một tài liệu tham khảo cho câu hỏi đóng của bạn mà bạn tự trả lời? Nó có thể đáng để thảo luận về Meta.
kevinarpe

Câu trả lời:


290

Các tài liệu liên quan có thể được tìm thấy ở đây:

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

Bắt đầu chương trình của bạn với các tham số sau:

-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

Ví dụ như thế này:

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=falsekhông nhất thiết phải có nhưng không có nó, nó không hoạt động trên Ubuntu. Lỗi sẽ là một cái gì đó như thế này:

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)

xem http://bugs.sun.com/bugdatabase/view_orms.do?orms_id=6754672

Ngoài ra, hãy cẩn thận với-Dcom.sun.management.jmxremote.authenticate=false việc cung cấp quyền truy cập cho bất kỳ ai, nhưng nếu bạn chỉ sử dụng nó để theo dõi JVM trên máy cục bộ thì không vấn đề gì.

Cập nhật :

Trong một số trường hợp, tôi không thể truy cập máy chủ. Điều này sau đó đã được sửa nếu tôi cũng đặt tham số này:-Djava.rmi.server.hostname=127.0.0.1


9
Hiện tại -Dcom.sun.man Quản lý.jmxremote.local.only = false cũng cần trên Centos
LenW

1
Nit pick: Thật kỳ lạ với tôi com.sun.management.jmxremotecó giá trị mặc định là true. (Cảm ơn bạn Sun!) Để trở nên cực kỳ rõ ràng, đặc biệt là với những người ít quen thuộc với quý tộc JMX, tôi sử dụng: com.sun.management.jmxremote=trueRef: docs.oracle.com/javase/8/docs/technotes/guides/man Quản lý / lỗi
kevinarpe

1
"-Djava.rmi.server.hostname" hoạt động như một cơ duyên đối với tôi!
Orhun D.

1
thiết lập tên máy chủ thành localhost là rất quan trọng nếu bạn đang cố gắng kết nối máy chủ từ xa thông qua đường hầm SSH, đây là một trường hợp rất phổ biến.
Nikhil Owalekar

1
Điều đó chỉ hoạt động nếu tôi vô hiệu hóa tường lửa trên máy chủ. Tôi đã mở cổng 9010 / tcp trong ví dụ này, tất nhiên, tôi cũng đã cố gắng thêm Dcom.sun.management.jmxremote.rmi.port=9011và mở trong tường lửa - vẫn không thể kết nối với tường lửa đang hoạt động. Có suy nghĩ gì không? Tôi có bỏ lỡ điều gì không?
Carmageddon

70

Chạy trong một Docker container đã giới thiệu một loạt các vấn đề bổ sung để kết nối, vì vậy hy vọng điều này sẽ giúp được ai đó. Cuối cùng tôi cần thêm các tùy chọn sau mà tôi sẽ giải thích bên dưới:

-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

Không giống như sử dụng jconsole cục bộ, bạn phải quảng cáo một IP khác với những gì bạn có thể thấy từ trong container. Bạn sẽ cần phải thay thế ${DOCKER_HOST_IP}bằng IP (Tên DNS) có thể phân giải bên ngoài của máy chủ Docker của bạn.

Cổng JMX Remote & RMI

Có vẻ như JMX cũng yêu cầu quyền truy cập vào giao diện quản lý từ xa ( jstat ) sử dụng một cổng khác để truyền một số dữ liệu khi phân xử kết nối. Tôi đã không thấy bất cứ nơi nào rõ ràng ngay lập tức jconsoleđể thiết lập giá trị này. Trong bài viết được liên kết, quá trình này là:

  • Hãy thử và kết nối từ jconsolekhi đăng nhập được kích hoạt
  • Thất bại
  • Chỉ ra cổng nào jconsoleđã cố sử dụng
  • Sử dụng iptables/ firewallquy tắc khi cần thiết để cho phép cổng đó kết nối

Trong khi nó hoạt động, nó chắc chắn không phải là một giải pháp tự động. Tôi đã chọn nâng cấp từ jconsole lên VisualVM vì nó cho phép bạn chỉ định rõ ràng cổng jstatdđang chạy. Trong VisualVM, thêm Máy chủ từ xa mới và cập nhật nó với các giá trị tương quan với các giá trị được chỉ định ở trên:

Thêm máy chủ từ xa

Sau đó nhấp chuột phải vào Kết nối máy chủ từ xa mới và Add JMX Connection...

Thêm kết nối JMX

Đừng quên kiểm tra hộp kiểm cho Do not require SSL connection. Hy vọng rằng, điều đó sẽ cho phép bạn kết nối.


-Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote.rmi.port=[...]cũng là chìa khóa trong trường hợp tạo đường hầm JMX / RMI thông qua SSH. Không có những thứ đó, các đối tượng từ xa được truy cập bằng IP công cộng / chính / ... của máy chủ sử dụng một số cổng ngẫu nhiên, không thể chuyển tiếp dễ dàng.
Thorsten Schöning

1
Tôi có thể xác nhận rằng bạn thực sự cần sử dụng IP bên ngoài để chứa IP. Ví dụ: nó không hoạt động với-Djava.rmi.server.hostname=0.0.0.0
raisercostin

Tôi không cần sử dụng ở DOCKER_HOST_IPbất cứ đâu - Tôi chỉ sử dụng localhostvà chuyển tiếp các cổng khi chạy hình ảnh docker: -p 9998:9998, -p 9999:9999v.v.
Barney

9

Lưu ý, Java 6 trong phiên bản mới nhất cho phép jconsole tự gắn vào một quy trình đang chạy ngay cả khi nó đã được bắt đầu mà không có câu thần chú JMX.

Nếu điều đó có sẵn cho bạn, cũng xem xét jvisualvm vì nó cung cấp nhiều thông tin về các quy trình đang chạy, bao gồm cả trình lược tả.


3
Điều này chỉ hoạt động nếu bạn đang chạy jconsole trên cùng một máy chủ với JVM mà bạn đang cố gắng theo dõi.
Xám

1
@ Thorbjorn Nếu tôi khởi động chương trình java của mình mà không có bất kỳ tham số nào và cố gắng kết nối với jconsole, tôi thấy trong chương trình của mình trong danh sách nhưng khi tôi cố gắng kết nối thì không thành công. Tôi nghĩ rằng đó là do thiếu chứng chỉ SSL. Tôi chỉ muốn xem bản demo do đó tôi phải sử dụng các tham số được chỉ định trong câu trả lời của user4953578 và nó đã hoạt động với tôi (JDK 1.7, Windows 8.1, 64 bit).
Thuyền trưởng Jack Sparrow

2
API đính kèm yêu cầu jconsole phải có JVM 32/64 bit giống như chương trình đã khởi chạy trên một số nền tảng.
Thorbjørn Ravn Andersen

1
Có thể vô hiệu hóa hành vi này?
kevinarpe

7

Tôi đang sử dụng WAS ND 7.0

JVM của tôi cần tất cả các đối số sau đây được theo dõi trong 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

Có câu trả lời của bạn đã làm việc cho tôi (JDK 1.7, windows 8.1 64 bit)
Thuyền trưởng Jack Sparrow

6

Trên Linux, tôi đã sử dụng các thông số sau:

-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

và tôi cũng chỉnh sửa /etc/hostsđể tên máy chủ phân giải thành địa chỉ máy chủ (192.168.0.x) thay vì địa chỉ loopback (127.0.0.1)


2

Chạy ứng dụng java của bạn với các tham số dòng lệnh sau:

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

Điều quan trọng là sử dụng tham số -Dcom.sun.man Quản lý.jmxremote.ssl = false nếu bạn không muốn thiết lập chứng chỉ kỹ thuật số trên máy chủ jmx.

Nếu bạn đã khởi động ứng dụng của mình trên máy có địa chỉ IP 192.168.0.1 , hãy mở jconsole , đặt 192.168.0.1:8855 vào trường Quy trình từ xa và bấm Kết nối .


Hành vi dự kiến ​​nếu bạn quên là -Dcom.sun.management.jmxremote.ssl=falsegì? Sẽ jconsolehiển thị một lỗi, hoặc nó chỉ lặng lẽ không kết nối?
amacleod

2

cùng với các tham số dòng lệnh bên dưới,

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

Đôi khi trong các máy chủ linux, kết nối imx không thành công. đó là bởi vì, trong máy chủ đám mây linux, trong / etc / hosts để tên máy chủ phân giải thành địa chỉ máy chủ.

Cách tốt nhất để khắc phục là ping máy chủ linux cụ thể từ máy khác trong mạng và sử dụng địa chỉ IP máy chủ đó trong

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

Nhưng đừng bao giờ dựa vào ipaddress mà bạn nhận được từ máy chủ linux bằng ifconfig.me. ip mà bạn nhận được ở đó là một mặt nạ có trong tệp máy chủ.


1

Trước tiên, bạn cần kiểm tra xem tiến trình java của bạn đã chạy với các tham số JMX chưa. Làm cái này:

ps -ef | grep java

Kiểm tra quá trình java của bạn, bạn cần theo dõi. Nếu bạn có thể thấy tham số jmx rmi Djmx.rmi.registry.port = xxxx thì hãy sử dụng cổng được đề cập ở đây trong java visualvm của bạn để kết nối từ xa dưới kết nối jmx.

Nếu nó không chạy qua cổng jmx rmi thì bạn cần chạy quy trình java của mình với các tham số được đề cập dưới đây:

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

Lưu ý: số cổng dựa trên sự lựa chọn của bạn.

Bây giờ bạn có thể sử dụng cổng này cho hình nón jmx. Đây là cổng 1234.


Bạn có thể thấy cổng 1234 đang được jmx sử dụng khi bạn chạy nó không? sudo lsof -i:1234không hiển thị bất cứ điều gì cho tôi
Gorgon_Union

1

Bước 1: Chạy ứng dụng bằng các tham số sau.

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

Các đối số trên liên kết ứng dụng với cổng 9999.

Bước 2: Khởi chạy jconsole bằng cách thực hiện lệnh jconsole trong dấu nhắc lệnh hoặc terminal.

Chọn 'Quy trình từ xa:' và nhập url dưới dạng {IP_Address}: 9999 và nhấp vào nút Kết nối để kết nối với ứng dụng từ xa.

Bạn có thể tham khảo liên kết này cho ứng dụng hoàn chỉnh.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.