JMX Client for Zookeeper - java

I am trying to workout a JMX Java client for Zookeeper instance for a custom monitoring web app. As provided in document, Zookeeper provides various statistics through JMX MBeans.
For the excercise, I am running Zookeeper intance locally in standalone mode on Windows 7 Enterprise using following arguments:-
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=10010
-Dzookeeper.jmx.log4j.disable=false
After running my zookeeper intance, I am able to connect to JMX beans using JConsole that correctly shows all the statistics :-
PROBLEM
While trying to connect using my own code I am getting java.net.ConnectException: Connection refused: connect error. Code that I am trying :-
public static void main(String[] args) throws Exception {
// service:jmx:rmi:///jndi/rmi://#{host}:#{port}/jmxrmi
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:10010/jmxrmi");
// This throws java.net.ConnectException !!!
JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();
ObjectName mbeanName = new ObjectName("org.apache.ZooKeeperService:name0=StandaloneServer_port2181");
ZooKeeperServerMXBean newProxyInstance = MBeanServerInvocationHandler.newProxyInstance(mbeanServerConnection,
mbeanName, ZooKeeperServerMXBean.class, true);
System.out.println("Created zoo mbean proxy");
System.out.println(newProxyInstance.getAvgRequestLatency());
}
Facing same problem while trying to connect using Java Visual VM.
What is the correct way to connect to Zookeeper MBean using Java code ?
UPDATE 1
There is 4 years old unresolved JIRA ticket that seems to be saying that there are two kind of ports that comes into play - jmx port & rmi port. The rmi port is generated randomly & I guess that is what needed while creating connection.
But then how JConsole is able to connect ?
UPDATE 2
This blog says that talking to remote JMX server over RMI protocol might be problem and suggests using JMXMP (JMX-Messaging Protocol) instead.
Now how do I exactly do I do that ?

Related

Jedis Issue - "Failed to connect to any host resolved for DNS name."

Whenever I try to connect to my Redis server from my Java application using Jedis, I get JedisConnectionException: Failed to connect to any host resolved for DNS name. The Java application runs on the same machine as the Redis server.
When I check the Redis server's status using systemctl, it's online and running without problems. I also connected to the Redis client via terminal using command-line on the Linux machine it is running on, authenticated and performed PING in which PONG was returned to make sure the Redis was up running.
Redis configuration
I have bind and requirepass un-commented in the redis.conf and looks like following (not my entire config, of course):
bind 127.0.0.1
requirepass mypassword
port 6379
This is the code I am using:
private void setupRedis(RedisCredentials credentials) {
final GenericObjectPoolConfig<Jedis> poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(0);
Jedis jedis;
try (JedisPool pool = new JedisPool(poolConfig, credentials.getIp(), credentials.getPort())) {
jedis = pool.getResource();
}
jedis.auth(credentials.getPassword());
jedis.connect();
log.info("Redis connection was established.")
}
I am a bit new to working with Redis therefor I wasn't sure on how much information to include in my post. All and any help is very much appreciated!
Tried
I tried the following code provided above multiple times. I have also tried restarting the Redis server and running the code again, with no successful try.
Expected to happen
For the application to log "Redis connection was establish" and to receive no errors in the process.
Resulted
The console logs the redis.clients.jedis.exceptions.JedisConnectionException: Failed to connect to any host resolved for DNS name and the application therefore obviously does not managed to establish a connection to Redis.

Can't connect to remote JMX running on localhost [duplicate]

This question already has answers here:
How to activate JMX on my JVM for access with jconsole?
(12 answers)
Closed last year.
I have two Kubernetes containers running in a pod, call them container A and B. A has a JMX server running. The Java options used to run the server are:
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.host=127.0.0.1
-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.host=localhost flag is set specifically so that JMX server isn't exposed to external clients.
Container B wants to monitor A using JMX over localhost only. The connection to JMX server in A is established using the following code:
String serverUrl = "service:jmx:rmi:///jndi/rmi://127.0.0.1:1234/jmxrmi";
JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceUrl, null);
MBeanServerConnection mBeanConn = jmxConnector.getMBeanServerConnection();
I was expecting to code to run without any issues since I'm able to connect to JMX port of A from B using telnet. However, when the Java code runs, an exception is thrown, first few lines of which are:
java.rmi.ConnectException: Connection refused to host: 10.8.0.88; nested exception is:
java.net.ConnectException: Connection refused (Connection refused)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:623) ~[na:1.8.0_312]
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216) ~[na:1.8.0_312]
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202) ~[na:1.8.0_312]
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:132) ~[na:1.8.0_312]
The client is using the private IP to connect to RMI server instead of connecting using 127.0.0.1 and is failing as JMX server is listening only on localhost. I need help figuring out the best way to allow communication between containers A & B over localhost.
Answering my own question for others who stumble upon the same problem. Adding the option -Djava.rmi.server.hostname=127.0.0.1 to the Java options solves the issue.

Is there a way to connect remotely to redis server using host-IP as host by different machine in Spring-Boot java application

I want to connect my redis server remotely which is running in Ubuntu Machine through windows, But not able to connect and getting Connection Refused Exception. Application is build with spring boot. Please suggest me how I can do it.
Below is my sample code:
#Override
public void expireDevices() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), "IP address", 6379, Protocol.DEFAULT_TIMEOUT);
try(Jedis jedis=pool.getResource()){
// Doing Something
}
expireWithBackgroundTask();
}
I second what Bhushan said, make sure that Redis is listening on a public IP. By default when you install it listens on localhost.
If your Redis server is installed on Ubuntu then go to /etc/redis/redis.conf file and find attribute something like bind 127.0.0.1. You need to find public IP of your Redis server and replace it with 127.0.0.1 then restart the Redis.
P.S. If you open Redis on public IP then go through Redis security risks

Embedded Jetty: How to set the JMX port in source code

We have system tests and when they start an Embedded Jetty boots via the setup. The Embedded Jetty includes a JMX server, too. Then we have tests which must connect to the JMX Server via:
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:<JMX_PORT>/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
The problem is we cannot connect from the tests to the JMX server when we do not know the JMX port up front. Has anybody a clue how to specify the JMX port up front when the Embedded Jetty is built within the source code? The system property stuff is of no help here.

How to get bound server address and port programmatically in Java EE?

At startup we need to get the server address and the http port of the running application. Until now we made it like this:
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName socketBindingMBean = new ObjectName("jboss.as:socket-binding-group=standard-sockets,socket-binding=http");
String host = (String) mBeanServer.getAttribute(socketBindingMBean, "boundAddress"),
Integer port = (Integer) mBeanServer.getAttribute(socketBindingMBean, "boundPort"));
Everything was fine but after migration from jBoss 7.1.1.Final to 7.1.3.Final we got the problem that the MBean isn't defined at server startup. That means everything is fine if I deploy the application on an already running jboss server, but if I start the server and the application is loaded up during server start MBeans are not there.
I don't know why but I have the feeling that jBoss makes sure, that out application is started/loaded before most of the MBeans. I had a small look and found out that following Mbeans are loaded after our application:
jboss.as:interface=..
jboss.as:socket-binding-group=..
jboss.as:subsystem=..
jboss.as:core-service=management.. (some)
So,
how can I force jBoss to load MBeans before my application?
is there another way/mbean where I can get my information?
I got the same issue in JBOSS Wildfly 8.1 . I solved the problem with the code below that worked for me to get server address and http port:
//http port
ManagementFactory.getPlatformMBeanServer().getAttribute(new ObjectName("jboss.as:socket-binding-group=standard-sockets,socket-binding=http"), "port");
//http adress
ManagementFactory.getPlatformMBeanServer().getAttribute(new ObjectName("jboss.as:interface=public"), "inet-address");

Categories