2008-12-01 34 views
17

Tôi hiện đang khởi động máy ảo Java của mình với các thuộc tính com.sun.management.jmxremote.* để tôi có thể kết nối với nó qua JConsole để quản lý và giám sát. Thật không may, nó lắng nghe trên tất cả các giao diện (địa chỉ IP) trên máy.Làm cách nào để JMX liên kết với một giao diện cụ thể?

Trong môi trường của chúng tôi, thường có các trường hợp có nhiều hơn một máy ảo Java chạy trên cùng một máy. Mặc dù có thể yêu cầu JMX lắng nghe trên các cổng TCP khác nhau (sử dụng com.sun.management.jmxremote.port), thay vào đó, JMX sử dụng cổng JMX chuẩn và chỉ liên kết với một địa chỉ IP cụ thể (thay vì tất cả chúng).

Điều này sẽ giúp việc tìm ra VM nào chúng ta đang kết nối thông qua JConsole dễ dàng hơn nhiều (vì mỗi VM có hiệu quả "sở hữu" địa chỉ IP của chính nó). Có ai đã tìm ra cách làm cho JMX lắng nghe trên một địa chỉ IP hoặc tên máy chủ không?

Trả lời

15

Nếu bất cứ ai khác sẽ được mất dây thần kinh của mình với điều này ... Sau 10 năm, cuối cùng họ cũng cố định nó!

Kể từ Java 8u102 -Dcom.sun.management.jmxremote.host liên kết với các IP chọn

see: https://bugs.openjdk.java.net/browse/JDK-6425769

8

Fernando đã cung cấp liên kết tới my blog post :) ..không phải là nhỏ. Bạn phải cung cấp RMIServerSocketFactoryImpl của riêng bạn để tạo ổ cắm trên địa chỉ mong muốn.

Nếu giao diện bên trong/bên ngoài là sự cố và bạn có quyền truy cập cục bộ thiết lập tường lửa cục bộ có thể dễ dàng hơn.

+0

Cảm ơn - Tôi không nghĩ nó sẽ đơn giản hay đẹp. :) –

-3

Câu trả lời được chấp nhận là khá cũ. Có một số dấu hiệu cho thấy Java bây giờ cung cấp một số tùy chọn để kích hoạt tính năng này. Ví dụ tôi đã thấy:

-Djava.rmi.server.hostname=<YOUR_IP> 

... cũng như ...

-Dcom.sun.management.jmxremote.host=<YOUR_IP> 

Tuy nhiên, ít nhất là trên hệ thống của tôi dưới jdk 1.7, những dường như không có bất kỳ tác - các Trình kết nối JMX vẫn liên kết với *. Một câu trả lời được cập nhật (với các phiên bản thích hợp cụ thể) sẽ được đánh giá cao. Điều này nên đơn giản.

+0

Không ai trong số này kiểm soát địa chỉ liên kết. 'java.rmi.server.hostname' không phải là mới, nó đã ở đó 17 năm, l và tôi nghi ngờ cái kia là mới. – EJP

+0

Tôi không nói họ là người mới. Tôi nói tôi đã nhìn thấy chúng và chúng không hoạt động. – sosiouxme

+0

Tôi đã hy vọng có một số cách mà thực sự làm việc mà không bị khủng khiếp. Đã không tìm thấy bất kỳ mặc dù. – sosiouxme

0

Tôi chưa thử điều này nhưng điều này có thể hữu ích.

mối phiền toái chính ở đây là không có cách nào dễ dàng để chỉ định địa chỉ IP của máy chủ để liên kết với, nó sẽ luôn ràng buộc với tất cả các giao diện. Thuộc tính 'java.rmi.server.hostname' không hoạt động và tôi không muốn chọn các cổng khác nhau cho tất cả các phiên bản khác nhau trên cùng một máy chủ.

Ngoài ra, tôi không muốn tạo RMIServerSocketFactory của riêng mình với tất cả các sự phức tạp liên quan đến nó, tôi đã sau một bản vá đơn giản cho mã hiện có.

Tôi đã sửa lỗi này bằng cách vá nhà máy socket JVM RMI mặc định là chịu trách nhiệm tạo ổ cắm máy chủ này. Hiện tại, nó hỗ trợ thuộc tính mới 'com.sun.management.jmxremote.host'.

Để làm điều này hoạt động, hãy lưu mã Java bên dưới vào một tệp có tên mặt trời/rmi/transport/proxy/RMIDirectSocketFactory.java.

Biên dịch và tạo jmx_patch.jar từ nó và đặt nó vào thư mục lib/ tomcat.

Sau đó, bạn cần phải thêm dòng sau vào bin/setenv.sh:

CLASSPATH = $ CLASSPATH: $ CATALINA_HOME/lib/mx_patch.jar

thêm tùy chọn này trong trường hợp tomcat khởi động

-Dcom.sun.management.jmxremote.host = 192.168.100.100"

này sau đó sẽ ràng buộc các dịch vụ JMX chỉ để giải quyết 192.168.100.100. 2 khác ngẫu nhiên RMI nghe cổng vẫn sẽ liên kết với tất cả các giao diện, nhưng điều đó là tốt như họ luôn chọn một cảng tự do anyway.

Bây giờ bạn có thể chạy nhiều trường hợp tomcat trên một máy chủ duy nhất với tất cả các cổng mặc định nguyên vẹn (ví dụ: 8080 cho JMX cho Tất cả bọn họ).

package sun.rmi.transport.proxy; 

import java.io.IOException; 
import java.net.InetAddress; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.rmi.server.RMISocketFactory; 

public class RMIDirectSocketFactory extends RMISocketFactory { 

    public Socket createSocket(String host, int port) throws IOException 
    { 
    return new Socket(host, port); 
    } 

    public ServerSocket createServerSocket(int port) throws IOException 
    { 
    String jmx_host = System.getProperty("com.sun.management.jmxremote.host"); 
    String jmx_port = System.getProperty("com.sun.management.jmxremote.port"); 

    // Allow JMX to bind to specific address 
    if (jmx_host != null && jmx_port != null && port != 0 && integer.toString(port).equals(jmx_port)) { 
    InetAddress[] inetAddresses = InetAddress.getAllByName(jmx_host); 
    if (inetAddresses.length > 0) { 
    return new ServerSocket(port, 50, inetAddresses[0]); 
    } 
} 

return new ServerSocket(port); 
    } 

}

0

Tôi chỉ cố gắng

-Dcom.sun.management.jmxremote.host =

với openjdk 1.8, và nó hoạt động tốt. Nó liên kết với addess đó (theo netstat) và tất cả đều đúng (và hoạt động).

+0

Đó là câu trả lời trùng lặp - có thể bạn muốn thêm nhận xét vào câu trả lời gốc? – Richlv

Các vấn đề liên quan