If you haven’t done it before, you’re like, “What is this thing? Why? What’s the use?” .

You may not know about it, but you’ve certainly been exposed to it at some point.

Spring Boot: Do you ever use Spring Boot to Actuator? It uses JMX. For example, if you have used JConsole or VisualVM, they also use JMX.

Below is the interface for JConsole and VisualVM.

How they use JMX is explained step by step.

What is a JMX

The full name of JMX is Java Management Extensions, which translates to Java Management Extensions and is used to manage and monitor Java programs. The most common ones are JVM monitoring and management, such as JVM memory, CPU utilization, thread count, garbage collection, and so on. In addition, it can also be used for log level dynamic modification, such as log4j, which supports JMX-style dynamic modification of log levels for online services. It is mainly used to make various monitoring tools, such as Spring Boot Actuator, JConsole and VisualVM mentioned at the beginning of this article.

JMX is not only a standard, a specification, but also an interface and a framework for Java management system. There are standards and specifications that allow developers to customize their own extensions, and as a framework, the JDK already provides common functionality, especially monitoring and management of the JVM.



The above diagram is a simple schematic diagram of the JMX architecture. A simple understanding is that the management system can manage various resources through JMX.

A management system can be thought of as an administrative client, such as JConsole, VisualVM, and the well-known Java monitoring toolkit of Metrics, or your own client implemented through the JMX interface. Various resources such as system configuration, JVM metrics, etc., or resources specific to your own project.

Here’s the point, JMX

This architecture diagram expands the above architecture schematic diagram. Here is a brief introduction from the bottom up.

MBean

JMX delivers messages through a variety of MBeans (Managed Beans). MBeans are what we usually call Java beans, but because they are special, they are called MBeans. Since it is a Bean, it contains properties and methods that allow the outside world to obtain the state of the managed resource and manipulate the behavior of the MBean. There are four types of MBeans in JMX, namely Standard MBeans, Dynamic MBeans, Open MBeans, and Model MBeans. The JDK provides MBeans mainly in the java.lang.management and javax.management packages. You can go in and have a look, you can see a lot of familiar figures, such as Memory related, Thread related, this is what we see in VisualVM, yes, that’s where the data comes from.

Honestly, we don’t need to worry too much about the differences between these types of MBeans, but let me give you a quick overview.

Standard MBeans are just plain old Java beans, and they are the simplest and most used in JMX. Mainly in the java.lang.management package.

Dynamic MBeans are a compromise, and since some of them already exist, it would be cumbersome and impractical to transform them into standard MBeans, there are Dynamic MBeans. The Dynamic of an interface in the javax.mail. Management. DynamicMBean here, it defined some interface methods, such as Dynamic gain attributes and set properties, etc.

There are also two types of MBeans: Open MBeans and Model MBeans, which are in fact dynamic MBeans as well.

The only difference between Open MBeans and other dynamic MBeans is that The former for limits on the parameters and return values of its public interface — only basic types or javax.mail. Management openmbean package ArrayType, CompositeType, TarbularType type, etc. This is mainly due to the distribution of the management system, and it is likely that the remote management system or even the MBServer layer will not have special classes in the MBean interface.

MBeanServer

MBeanServer is responsible for managing MBeans. Generally, there is only one MBeanServer per JVM. All MBeans should be registered with MBeanServer and provided with external services through MBeanServer. General use ManagementFactory. GetPlatformMBeanServer () method gets the current MBeanServer within the JVM.

Adapters and connectors

Once the written MBean is registered with the MBeanServer, the functionality is ready. Adapters and connectors are ways to expose these capabilities. An HTTP adapter, for example, exposes functionality in the HTTP protocol so that it can be used in the browser. However, the JDK only provides the standard implementation of adapters, and there is no specific implementation. The more commonly used is HtmlAdaptorServer, which needs the support of the jmxtools.jar package.

Connectors are the most common for various clients. The JDK provides the RMI connector as the default connector, which is used by JConsole and VisualVM.

Implement and use an MBean

Although Java provides standards and rules for implementing MBeans, we rarely need to develop MBeans. The vast majority of developers only have access to JDK or third-party defined MBeans, and very few, if any, third parties have implemented MBeans. Tomcat and Spring Boot Actuator.

Define the MBean interface and entity class

Public interface userMBean {String getName(); String getPassword(); String getPhone(); void say(); }
Public class User implements UserMBean {@Override public String getName() {return "kite "; } @Override public String getPassword() {return "Password is not visible "; } @Override public String getPhone() { return "18900000000"; } @Override public void say() { System.out.println("Hello JMX"); }}

Entity classes need to inherit from the MBean interface class, and the naming rule for interface classes is “Entity class name +MBean”, which is a fixed rule.

Register the defined MBean with the MBeanServer

public static void main(String[] args) throws Exception { MBeanServer server = ManagementFactory.getPlatformMBeanServer(); ObjectName userName = new ObjectName("FengZheng:type=customer,name=customerUserBean"); server.registerMBean(new User(), userName); Try {/ / this is an important step, registered a port, after binding the url for the client connection by way of rmi JMXConnectorServer LocateRegistry. CreateRegistry (8999); // The end of the URL path is optional, but if you need to use JConsole to connect, You must use jmxrmi JMXServiceURL url = new JMXServiceURL (" service: JMX: rmi: / / / jndi/rmi: / / localhost: 8999 / jmxrmi "); JMXConnectorServer jcs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server); System.out.println("begin rmi start"); jcs.start(); System.out.println("rmi start"); } catch (RemoteException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Thread.sleep(60 * 60 * 1000); }

ManagementFactory. GetPlatformMBeanServer () gets the current JVM MBeanServer, ObjectName is the only label, an an MBeanServer there cannot be repeated. The full format “custom namespace :type= custom type,name= custom name”. Of course, you can declare only type without name.

Use JConsole to view

JConsole is a built-in JDK tool that can be launched in the bin directory of ${JAVA_HOME}. After startup, locate the process in the local process where the main method was started in the previous step.

Above JConsole are the Memory, Thread, Class, and so on tabs. Click on the last MBean to see all the MBeans defined for the current JVM. You can see the system-defined MBean, as well as the MBean we just defined.

Click on the property to view the value of the property on the right side, and under the action menu item, you can see the method we defined and call it.

Use RMI to connect

RMI is usually used to connect to remote services, but local processes can also be used. This is also the first step in implementing a connection to a remote service client. When we registered the MBean, did you notice that after the registration is completed, there is a large piece of code, this code is used to open the RMI connection, open port 8999 as the RMI access port, then the client can use the fixed connection string to connect.

Connection string format of the service: JMX: rmi: / / / jndi/rmi: / / host: port/jmxrmi

public class Client { public static void main(String[] args) throws IOException, Exception, NullPointerException { String jmxUrl = "service:jmx:rmi:///jndi/rmi://localhost:8999/jmxrmi"; monitor(jmxUrl); } public static void monitor(String url) throws Exception{ JMXServiceURL jmxServiceURL = new JMXServiceURL (url); JMXConnector jmxc = JMXConnectorFactory.connect(jmxServiceURL, null); MBeanServerConnection msc = jmxc.getMBeanServerConnection(); String[] domains = msc.getDomains(); for (String domain : domains) { System.out.println(domain); }}}

According to the connection string to obtain a JMXServiceURL object first, then by JMXConnectorFactory. The connect method obtaining JMXConnector, Then getMBeanServerConnection via getMBeanServerConnection. After that, you can get all the MBeans. GetDomains are the methods that get all the namespaces, which we defined above as “FengZheng”, and Jmimplementation, java.lang, and so on, so that’s what we’ll see in JConsole.

I also want to introduce the system definition of JVM related MBeans and the specific way to manipulate MBeans. I also wrote a Web version of the client when I wrote this, the function is basically the same as JConsole, VisualVM, but also support local and remote connections. I’ll introduce you to the next post together. I’ll show you two screenshots first.

Support for remote and local connections

View all the MBeans, and the properties of the MBeans, and you can call methods.

Dynamic view of CPU, heap, Metasapce (Java1.8), classes, threads, etc

More dry goods please pay attention to the public number: ancient kites