1, JMX
JMX (Java Management Extensions) is a framework for embedding management functions into applications. It is a set of standard agents and services. The service is the Java program performance monitoring program officially provided by JDK. Support remote access and extension, that is, customize the performance parameters of monitoring. It provides three levels of calls: network, API and client. In fact, the Java platform uses JMX as the standard interface for management and monitoring. As long as any program accesses this interface according to the JMX specification, it can obtain all management and monitoring information. Common operation and maintenance monitoring tools such as Zabbix and Nagios monitor the JVM itself through JMX.
2, Application scenario
The management page of the middleware software WebLogic is developed based on JMX, while JBoss is based on JMX architecture. There are several ways to modify some parameters as follows:
-
It is written in the code, and it needs to be modified when it needs to be changed, and then it is recompiled and released.
-
It is written in the configuration file, such as java properties. When it needs to be changed, only the configuration file needs to be modified, but the system must be restarted to take effect.
-
Write a piece of code to cache the configuration value. When the system obtains the configuration value, it will first check whether the configuration file has been changed. If there is any change, it will get the latest value from the configuration. Otherwise, it will be read from the cache. For example, it will read the data of Apollo configuration center.
-
JMX is used to gather the properties to be configured in a class, then write an MBean, and then perform relevant configuration. JMX provides the JConsole tool page to facilitate modification of parameter values.
The structure of JMX is divided into three layers: the basic layer (mainly MBean), the adaptation layer (adapter) and the interface layer (Connector)
3, MBean
-
JMX calls all managed resources MBeans (managedbeans). These MBeans are all managed by MBeanServer. If you want to access MBeans, you can use the access interface provided by MBeanServer, such as RMI or HTTP.
-
Using JMX does not need to install any additional components, nor does it need a third-party library, because MBeanServer has been built into the JavaSErver standard library. JavaSE also provides a JConsole program for RMI connection to MBeanServer, so that the whole process can be managed.
-
In addition to the JVM registering its own resources in JMX as MBeans, our own configuration and monitoring information can also be registered in JMX as MBeans, so that the hypervisor can directly control the MBeans we expose.
MBean s are divided into the following four types:
type | describe |
---|---|
standard MBean | This type of MBean is the simplest. The resources it can manage (including attributes, methods, and time) must be defined in the interface, and then the MBean must implement this interface. Its naming must also follow certain specifications. For example, if our MBean is Hello, the interface must be HelloMBean. |
dynamic MBean | javax.management.DynamicMBean interface must be implemented, and all properties and methods are defined at runtime |
open MBean | The specification of this MBean is not perfect and is being improved |
model MBean | Compared with standard and dynamic MBeans, you can use javax.management.ModelMBean instead of writing MBean classes RequiredModelMBean. RequiredModelMBean implements the ModelMBean interface, and ModelMBean extends the DynamicMBean interface. Therefore, similar to DynamicMBean, the management resources of model MBean are also defined at runtime. Unlike dynamicmbeans, the resources managed by dynamicmbeans are generally defined in dynamicmbeans (those resources are managed only at runtime), while the resources managed by model MBeans are not in MBeans, but outside (usually a class). Only at runtime, they are added to model MBeans through the set method. The following examples will be described in detail |
- Adaptation layer
MBeanServer mainly provides registration and management of resources
- Access layer
Provide remote access
- usage method
- Write the management interface and monitoring data provided by MBean.
- Register MBean
4, Examples
- java Native example
- Interface
public interface HelloMBean { public String getName(); public void setName(String name); public String printHello(); public String printHello(String whoName); }
- Interface implementation class
public class Hello implements HelloMBean{ private String name; @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; } @Override public String printHello() { return "Hello "+ name; } @Override public String printHello(String whoName) { return "Hello " + whoName; } }
- Agent
public class HelloAgent { public static void main(String[] args) throws Exception { //create mbean server MBeanServer server = ManagementFactory.getPlatformMBeanServer(); //create object name ObjectName objectName = new ObjectName("jmxBean:name=hello"); //create mbean and register mbean Hello hello = new Hello(); hello.setName("hello"); server.registerMBean(hello, objectName); /** * JMXConnectorServer service */ //This sentence is very important and cannot be missing! After registering a port and binding the url, the client can use rmi to connect to JMXConnectorServer through url Registry registry = LocateRegistry.createRegistry(1099); //Construct JMXServiceURL JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi"); //Create JMXConnectorServer JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, null, server); //start-up cs.start(); } }
After starting the Agent, you can connect through the Jconsole. You can see that there are two printHello methods. One is to input parameters by yourself, and the other is to write parameters. Both parameters can be called in the Jconsole.
- springboot project
- Add the annotation @ EnableMBeanExport in the launcher to tell spring to automatically register MBean s
@SpringBootApplication //Add the annotation @ EnableMBeanExport in the launcher to tell spring to automatically register MBean s @EnableMBeanExport public class JmxApplication { public static void main(String[] args) { SpringApplication.run(JmxApplication.class, args); } }
- Write MBean. Here, take the configuration blacklist data as an example. Get configuration data, add data and delete data through JConsole. It takes effect immediately after configuration without recompiling and publishing code
@Component //Indicates that this is an MBean that will be registered to JMX. objectName specifies the name of this MBean, usually with company: name = XXX (company name); To classify MBeans @ManagedResource(objectName = "company:name = blackList", description = "blackList of Ip address") public class BlackListMBean { private static Set<String> ips = new HashSet<>(); static { ips.add("123"); ips.add("234"); } /** * For attributes, annotate with the @ ManagedAttribute annotation. This MBean only has the get attribute, not the set * Property, indicating that this is a read-only property. * @return */ @ManagedAttribute(description = "Get IP addresses in blacklist") public String[] getBlacklist() { return ips.toArray(new String[1]); } /** * For operations, annotate with @ ManagedOperation annotation. Operations include addBlacklist() and * removeBlacklist()Other methods such as shouldBlock() are not exposed to JMX. * @param ip */ @ManagedOperation @ManagedOperationParameter(name = "ip", description = "Target IP address that will be added to blacklist") public void addBlacklist(String ip) { ips.add(ip); } @ManagedOperation @ManagedOperationParameter(name = "ip", description = "Target IP address that will be removed from blacklist") public void removeBlacklist(String ip) { ips.remove(ip); } public boolean shouldBlock(String ip) { return ips.contains(ip); } }
- Interception interface and implementation class
public interface IpInterceptor { boolean preHandle(String ip); }
@Component @Slf4j public class BlackIpHandle implements IpInterceptor { @Autowired private BlackListMBean blackListMBean; @Override public boolean preHandle(String ip) { return blackListMBean.shouldBlock(ip); } }
@Controller public class JmxController { @Resource BlackIpHandle blackIpHandle; @RequestMapping("/test/Jmx/{str}") public void jmxTest(@PathVariable(value = "str") String str) { if (blackIpHandle.preHandle(str)) { System.out.println("Interception succeeded"); return; } System.out.println("Interception failed"); return; } }
Note: there is a limitation in using jconsole to connect JVMs directly through Local Process, that is, jconsole and the running JVMs must be on the same machine. If you want to connect remotely, first open the JMX port. When we start AppConfig, we need to pass in the following JVM startup parameters:
-Dcom.sun.management.jmxremote.port=port-number
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false