Java monitoring Basics - use JMX to monitor and manage Java programs

This article introduces the related concepts and specific usage of Java JMX technology.

1. What is JMX?

Java Management Extensions (JMX) technology is the standard function of Java SE platform. It provides a simple and standard way to monitor and manage resources. It gives a clear structure and design pattern for how to define a resource. It is mainly used to monitor and manage the running status of Java applications, equipment and resource information, and the running status of Java virtual machine. JMX can be dynamic, so it can also be dynamically monitored and managed during resource creation, installation and implementation. The jconsole provided by JDK is a monitoring tool implemented using JMX technology.

When JMX technology is used, a Java object called MBean or MXBean is defined to represent the specified resources to be managed, and then the resource information can be registered with the MBean Server to provide external services. MBean Server acts as an agent for providing services externally and managing MBean resources internally. Such an elegant design makes MBean resource management and MBean Server agent completely independent, so that they can freely control MBean resource information.

JMX is not only used for local management, JMX Remote API adds remote function to JMX, so that it can remotely monitor and manage applications through the network.

2. Why use JMX technology?

JMX technology provides Java developers with a simple, flexible and standard way to monitor Java applications. Thanks to the relatively independent architecture design, JMX can be smoothly integrated into various monitoring systems.

Here are some specific advantages of JMX:

  1. Out of the box monitoring function, JMX is a standard part of Java SE. It provides basic management functions such as resource management, service hosting and remote monitoring, which can be directly enabled.
  2. JMX technology provides a general and standard management mode of resources, systems, applications and networks, which can not only be used locally and remotely; It can also be extended to other scenarios, such as Java EE applications.
  3. JMX technology provides the function of monitoring JVM status. JMX has built-in monitoring function for JVM, and can monitor and manage JVM, which is very convenient.
  4. JMX architecture design is excellent, and the component design can be extended freely.
  5. JMX technology strictly complies with existing Java specifications, such as JNDI specification.
  6. JMX can freely integrate with other management solutions. Thanks to the open JMX API, resources in JMX can be managed through web services.

3. Technical architecture of JMX

JMX technical architecture is mainly composed of resource management (MBean/MXBean) module, resource agent module (MBean Server) and remote management module (Remote API). The following picture is from Wikipedia and shows the relationship between the three modules.

3.1. Resource management MBean

Resource management is identified as the Probe Level in the architecture. In JMX, MBeans or mxbeans are used to represent a resource (hereinafter referred to as MBeans). Resources are accessed and managed through MBeans, so MBeans often contain resource attributes and operation methods.

JMX has carried out multi-dimensional resource detection on the JVM, so you can easily start the JMX agent to access the built-in JVM resource detection, so as to remotely monitor and manage the JVM through JMX technology.

The following lists JMX resource detection classes for JVM s, which can be used directly.

Resource interfaceManaged resourcesObject NameNumber of instances in VM
ClassLoadingMXBeanClass loadingjava.lang:type= ClassLoading1
CompilationMXBeanAssembly systemjava.lang:type= Compilation0 or 1
GarbageCollectorMXBeangarbage collection java.lang:type= GarbageCollector, name=collectorName1 or more
LoggingMXBeanLog systemjava.util.logging:type =Logging1
MemoryManagerMXBeanMemory pooljava.lang: typeMemoryManager, name=managerName1 or more
MemoryPoolMXBeanMemoryjava.lang: type= MemoryPool, name=poolName1 or more
MemoryMXBeanMemory systemjava.lang:type= Memory1
OperatingSystemMXBeanoperating systemjava.lang:type= OperatingSystem1
RuntimeMXBeanRuntime systemjava.lang:type= Runtime1
ThreadMXBeanThread systemjava.lang:type= Threading1

The following code example demonstrates a code example that uses JMX to detect some information about the JVM.

package com.wdbyte.jmx;

import java.lang.management.CompilationMXBean;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryManagerMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.util.List;
import java.util.stream.Collectors;

/**
 * JMX JVM
 *
 * @author https://www.wdbyte.com
 */
public class JavaManagementExtensions {

    public static void main(String[] args) {
        OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
        String osName = operatingSystemMXBean.getName();
        String osVersion = operatingSystemMXBean.getVersion();
        int processors = operatingSystemMXBean.getAvailableProcessors();
        System.out.println(String.format("Operating system:%s,edition:%s,Processor:%d individual", osName, osVersion, processors));

        CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean();
        String compilationMXBeanName = compilationMXBean.getName();
        System.out.println("Compiling system:" + compilationMXBeanName);

        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
        long max = heapMemoryUsage.getMax();
        long used = heapMemoryUsage.getUsed();
        System.out.println(String.format("Memory used:%dMB/%dMB", used / 1024 / 1024, max / 1024 / 1024));

        List<GarbageCollectorMXBean> gcMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
        String gcNames = gcMXBeans.stream()
            .map(MemoryManagerMXBean::getName)
            .collect(Collectors.joining(","));
        System.out.println("Garbage collector:" + gcNames);
    }
}

The following results can be obtained by running:

Operating system: Mac OS X,Version: 11.6,Processor: 12
 Compiling system: HotSpot 64-Bit Tiered Compilers
 Memory used: 3 MB/4096MB
 Garbage collector: G1 Young Generation,G1 Old Generation

3.2. Resource agent MBean Server

Resource agent MBean Server is the agent of MBean resources. MBean resources can be used for remote management through MBean Server. MBean resources and MBean Server are often in the same JVM, but this is not necessary.

If you want the MBean Server to manage MBean resources, you must first register the resources with the MBean Server. Any JMX compliant MBean resources can be registered. Finally, the MBean Server will expose a remote communication interface to provide services.

3.3. JMX remote management

JMX API s can be accessed through network protocols, such as HTTP protocol, SNMP (Network Management Protocol) protocol, RMI remote call protocol, etc. JMX technology implements RMI remote call protocol by default.

Benefiting from the full decoupling of resource management MBean s, the resource management function can be easily extended to other protocols, such as web page management through HTTP.

4. Specific use of JMX

In the resource management MBean section, it has been demonstrated to use JMX to obtain JVM operation information. What if you want to customize a resource MBean?

The following is an example to simulate a memory resource MBean, and finally manage it remotely.

4.1. Write resource management MBean s

The preparation of MBeans must comply with the design specifications of JMX. MBeans are very much like a special Java Bean, which requires an interface and an implementation class. MBean resource interface always ends with MBean or MXBean, and the implementation class should be named after the interface removes MBean or MXBean.

Write a memory resource management MBean interface, which is defined as follows:

package com.wdbyte.jmx;

/**
 * @author https://www.wdbyte.com
 */
public interface MyMemoryMBean {

    long getTotal();

    void setTotal(long total);

    long getUsed();

    void setUsed(long used);

    String doMemoryInfo();
}

Then implement this interface:

package com.wdbyte.jmx;

/**
 * @author https://www.wdbyte.com
 */
public class MyMemory implements MyMemoryMBean {

    private long total;
    private long used;

    @Override
    public long getTotal() {
        return total;
    }

    @Override
    public void setTotal(long total) {
        this.total = total;
    }

    @Override
    public long getUsed() {
        return used;
    }

    @Override
    public void setUsed(long used) {
        this.used = used;
    }

    @Override
    public String doMemoryInfo() {
        return String.format("Use memory: %dMB/%dMB", used, total);
    }

}

This example is in mymemory There are only two long basic type attributes in Java, so the interface ends with MBean. If the attribute in the resource implementation class is a reference to the custom entity class, the interface needs to end with MXBean.

This completes the creation of the number of threads resource MBean, where total and used are the resource attributes and doMemoryInfo is the resource operation method.

4.2. Register resources to MBean Server

Through the JMX architecture diagram above, we know that MBean resources need to be registered with MBean Server for proxy before they can be exposed to the outside for calling. Therefore, if we want to remotely manage our customized MyMemory resources, we need to conduct resource proxy first.

package com.wdbyte.jmx;

import java.lang.management.ManagementFactory;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;

/**
 * @author https://www.wdbyte.com
 */
public class MyMemoryManagement {

    public static void main(String[] args) throws MalformedObjectNameException, NotCompliantMBeanException,
        InstanceAlreadyExistsException, MBeanRegistrationException, InterruptedException {
        // Get MBean Server
        MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
        MyMemory myMemory = new MyMemory();
        myMemory.setTotal(100L);
        myMemory.setUsed(20L);
        // register
        ObjectName objectName = new ObjectName("com.wdbyte.jmx:type=myMemory");
        platformMBeanServer.registerMBean(myMemory, objectName);

        while (true) {
            // Prevent exit
            Thread.sleep(3000);
            System.out.println(myMemory.doMemoryInfo());
        }
    }
}

After startup, you can see that the console prints our customized memory information every three seconds.

Use memory: 20MB/100MB
 Use memory: 20MB/100MB

Start the Java program without adding any JVM parameters. JMX can only be accessed on the current machine. If you want to access remotely through the network, you need to specify the current machine ip and open port at startup.

$ java -Dcom.sun.management.jmxremote=true \  # Turn on remote access
-Dcom.sun.management.jmxremote.port=8398 \		# Custom JMX port
-Dcom.sun.management.jmxremote.ssl=false \		# Whether to use SSL protocol, the production environment must be enabled
-Dcom.sun.management.jmxremote.authenticate=false \ # Whether certification is required, the production environment must be opened
-Djava.rmi.server.hostname=150.158.2.56 YourClass.java # Current machine ip

4.3. Remote management jconsole

Jconsole is Java's own monitoring and management tool based on JMX technology. If JDK environment variables have been configured, you can directly start the console through jconsole command.

After starting jconsole, the Java processes on the current machine will be listed. Here, select the java process you want to monitor. After connecting, you will be prompted with an unsafe protocol because the HTTPS protocol will not be configured for Java program startup by default.

After connecting, you can see multi-dimensional JVM monitoring information, which is obtained by reading the JVM resource MBean information.

Thread information is listed on the following page. Pay attention to the thread information at the bottom. RMI TCP threads can be seen. This also proves that JMX performs remote management through RMI protocol by default.

On the MBean page, you can browse all the manageable MBean information, and you can also see our customized com wdbyte. The memory information in JMX can even modify the used variable directly.

After modification, the console log changes immediately. You can see that the modification has been successful.

Use memory: 20MB/100MB
 Use memory: 20MB/100MB
 Use memory: 20MB/100MB
 Use memory: 30MB/100MB

During the operation, you can call the doMemoryInfo method. After calling, you can see that the memory used in the return value has been updated from 20MB at startup to 30MB.

Keywords: Java JavaEE Back-end

Added by kevingarnett2000 on Thu, 09 Dec 2021 15:29:45 +0200