简体   繁体   English

多线程 JMX 客户端

[英]Multi threading JMX client

I am trying to implement a JMXclient to monitor remote JVM.我正在尝试实现一个 JMXclient 来监视远程 JVM。 I obtain the mbeanserver connection from a main method and pass it to a thread which search for memory usage.我从 main 方法获取 mbeanserver 连接并将其传递给搜索内存使用情况的线程。 Problem is when I do this i get an error saying "The client has been closed".问题是当我这样做时,我收到一条错误消息,提示“客户端已关闭”。 But if I run the program without threads it works perfectly.但是如果我在没有线程的情况下运行程序,它就可以完美运行。

public class ESBMonitor {
     private static TreeSet<ObjectName> mbeansNames = null;

     public static void main(String[] args) throws IOException {
         RemoteConnector.defaultConnector();
         MBeanServerConnection remote = RemoteConnector.getRemote();
         //MemoryExtractor.getMemoryInfo();
         MemoryExtractor memoryExtractor = new MemoryExtractor();
         memoryExtractor.start();
         RemoteConnector.closeConnection();
     }
}



public class RemoteConnector {

private static MBeanServerConnection remote = null;
private static JMXConnector connector = null;
private static final Logger logger= LogManager.getLogger(RemoteConnector.class);

public static void defaultConnector() {
    try {
        JMXServiceURL target = new JMXServiceURL
                ("service:jmx:rmi://localhost:11111/jndi/rmi://localhost:9999/jmxrmi");
        //for passing credentials for password
        Map<String, String[]> env = new HashMap<String, String[]>();
        String[] credentials = {"admin", "admin"};
        env.put(JMXConnector.CREDENTIALS, credentials);

        connector = JMXConnectorFactory.connect(target, env);
        remote = connector.getMBeanServerConnection();
        logger.info("MbeanServer connection obtained");

    } catch (MalformedURLException e) {
        logger.error(e.getStackTrace());
    } catch (IOException e) {
        logger.error(e.getStackTrace());
    }
}

public static MBeanServerConnection getRemote() {
    return remote;
}



public static synchronized Object getMbeanAttribute(ObjectName bean, String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException, InstanceNotFoundException, IOException {
    return remote.getAttribute(bean,attribute);
}


}




public class MemoryExtractor extends Thread{

final static Logger logger = Logger.getLogger(MemoryExtractor.class);
private static MBeanInfo memoryInfo;
private static ObjectName bean = null;
private static double MEMORY = 0.05;
private static long TIMEOUT = 3000;

public static void getMemoryInfo() {
    try {
        bean = new ObjectName("java.lang:type=Memory");
        checkWarningUsage();

    } catch (MalformedObjectNameException e) {
        logger.error("MemoryExtractor.java:25 " + e.getMessage());
    }
}

public static boolean checkWarningUsage() {
        try {
            logger.info("MemoryExtractor.java:46 Acessing memory details");
            CompositeData memoryUsage = (CompositeData) RemoteConnector.getMbeanAttribute(bean,"HeapMemoryUsage");


        } catch (Exception e) {
            logger.error("MemoryExtractor.java:58 " + e.getMessage());
        }
    return false;
}

public void run(){
    while (true){
        getMemoryInfo();
    }   
}
}

No matter I synchronize or not problem will still be there.无论我同步与否,问题仍然存在。

Stack trace堆栈跟踪

java.io.IOException: The client has been closed.
at com.sun.jmx.remote.internal.ClientCommunicatorAdmin.restart(ClientCommunicatorAdmin.java:94)
at com.sun.jmx.remote.internal.ClientCommunicatorAdmin.gotIOException(ClientCommunicatorAdmin.java:54)
at javax.management.remote.rmi.RMIConnector$RMIClientCommunicatorAdmin.gotIOException(RMIConnector.java:1474)
at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.getAttribute(RMIConnector.java:910)
at org.wso2.connector.RemoteConnector.getMbeanAttribute(RemoteConnector.java:55)
at org.wso2.jvmDetails.MemoryExtractor.checkWarningUsage(MemoryExtractor.java:47)
at org.wso2.jvmDetails.MemoryExtractor.run(MemoryExtractor.java:79)

You are caching the reference to the JMXConnector as a static in your RemoteConnector class, so there's only ever one connection.您将 JMXConnector 的引用缓存为RemoteConnector类中的static ,因此只有一个连接。 As soon as the first thread closes that singleton connection, the next time any other thread attempts to call something it will fail because you've already closed the connection at that point.一旦第一个线程关闭该单例连接,下次任何其他线程尝试调用某些东西时它就会失败,因为您在那时已经关闭了连接。

If you want to have multiple threads, then either you should close the connection when all threads have finished, or have one connection per thread.如果您想拥有多个线程,那么您应该在所有线程完成后关闭连接,或者每个线程有一个连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM