问题
I have a tomcat application on the remote host and need to connect it by JConsole. Application starts with params:
IP=`ifconfig eth0 | grep 'inet addr:' | cut -d ':' -f2 | cut -d ' ' -f1`
-Dcom.sun.management.jmxremote
-Djava.rmi.server.hostname=$IP
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
Port 9999 is open, IP
value is valid, I checked it. I can access it by telnet (telnet <my_host> <my_port>
). Netstat:
netstat -a | grep LISTEN
tcp 0 0 *:9999 *:* LISTEN
But I can't connect it via jconsole, I allways get same error:
Connection Failed: Retry?
But netstat -a
shows that the connection is ESTABLISHED
I tried different addresses:
<my_host>:<my_port>
service:jmx:rmi://<my_host>:<my_port>/jndi/rmi://<my_host>:<my_port>/jmxrmi
service:jmx:rmi:///jndi/rmi://<my_host>:<my_port>/jmxrmi
I also tried to add files .../conf/remote.users
and .../remote.acl
and write pathes to that files in prorerties -Dcom.sun.management.jmxremote.password.file
and -Dcom.sun.management.jmxremote.access.file
but it had no effect.
When I deploy this app on my local machine, i can connect to it at "localhost:9999"
Help somebody, what could be the problem?
回答1:
If you are able to telnet <my_host> <my_port>
then issue must be because of Firewall, since in JMX once handshake done on configured port i.e then a new port is assigned for further communication and probably your Firwall is not allowing to open a new port.
To cross check simply try to run below Java JMX Client which will try to display HeapMemoryUsage.
import java.util.Set;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class JMXDemo {
private static final String HOST = ""; // configure host <my_host> here
private static final String PORT = ""; // configure port <my_port> here
private static void testJMX() throws Exception {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://" + HOST + "/jndi/rmi://" + HOST + ":" + PORT
+ "/jmxrmi");
JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
try {
MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();
ObjectName mbeanName = new ObjectName("java.lang:type=Memory");
javax.management.openmbean.CompositeDataSupport obj = null;
obj = (javax.management.openmbean.CompositeDataSupport) mbeanServerConnection.getAttribute(mbeanName,
"HeapMemoryUsage");
Set<String> keySet = obj.getCompositeType().keySet();
for (String key : keySet) {
System.out.print(key + "=" + obj.get(key) + ", ");
}
} finally {
jmxConnector.close();
}
System.out.println("\n==========================");
}
public static void main(String args[]) throws Exception {
testJMX();
}
}
To Enable JMX logging Create a logging.properties file
handlers= java.util.logging.ConsoleHandler
.level=ALL
java.util.logging.FileHandler.pattern = jmx.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
java.util.logging.ConsoleHandler.level = FINEST
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
// Use FINER or FINEST for javax.management.remote.level - FINEST is
// very verbose...
//
javax.management.level=FINEST
javax.management.remote.level=FINEST
java.security.debug=all
Compile the java code and run using below command
java -Djava.util.logging.config.file=./logging.properties JMXDemo
This will print so many logs on console, you can grep "port".
回答2:
Write a basic Java program:
import java.util.*;
import java.io.*;
class testCode{
public static void main(String args[]){
System.out.println("just killing time...do not enter a value and kill me ");
Scanner sc = new Scanner(System.in);
sc.nextInt();
}
}
Compile and then run it with the following parameters:
java -Dcom.sun.management.jmxremote=true \
-Dcom.sun.management.jmxremote.port=12345 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=10.1.10.167 \
testCode
Replace rmi.server.hostname
with the IP of the machine where Java code is being executed, then use jconsole
to remote connect with 10.1.10.167:12345
. No user id and password required.
回答3:
try all these flags:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=$IP
if Dcom.sun.management.jmxremote.local.only is true, it will block remote connections.
来源:https://stackoverflow.com/questions/35982953/cannot-connect-to-remote-jmx