Java Management extensions (Java Management extension,jmx) started with jdk1.4, but were added to the JDK from 1.5 and put the APIs inside the Java.lang.management package.
If a Java object can be managed by a manager that follows the JMX specification, the Java object can be called a resource that can be managed by JMX.
To make a Java object manageable, you must create a corresponding Mbean object and manage the corresponding Java object through these Mbean objects. When you have an MBean class, you need to instantiate it and register it on the mbeanserver.
There are four types of mbean, namely, standard type Mbean, dynamic type Mbean, open type Mbean, and model type Mbean.
Note:
A Java process can have several different names of the Mbeanserver, each MBS is a separate container, with the management Mbean each MBS can register multiple RMI port,http port, etc. platformmbeanserver was created by the JVM and added some system Mbean, such as CPU, memory, network, thread, etc.
1, the use of the machine
When we start the Java process, we often use the Jps,jinfo,jmap,jstat and other JDK commands to query the state of the process, and the principle is that when the Java process is started, a "localconnectoraddress" is created for the native connection. "In the current user directory, when connecting using JPS, the current user directory is taken to" localconnectoraddress "and connected.
@Test public void Test1 () {list<virtualmachinedescriptor> VMS = virtualmachine.list ();
for (Virtualmachinedescriptor Desc:vms) {virtualmachine vm;
try {System.out.println ("desc:" + desc);
SYSTEM.OUT.PRINTLN ("Process ID:" +desc.id ());
VM = Virtualmachine.attach (DESC);
catch (Exception e) {e.printstacktrace ();
Continue
} Jmxconnector connector = null;
try {Properties props = vm.getagentproperties (); For (Map.entry<object, object> entry:props.entrySet ()) {System.out.println (Entry.getkey () + "->" + Entry.)
GetValue ());
String connectoraddress = Props.getproperty ("com.sun.management.jmxremote.localConnectorAddress");
if (connectoraddress = = null) {System.out.println ("connectoraddress is null");
Continue
} System.out.println ("conn:" + connectoraddress);
The following code is used to connect the specified JMX, local or remote Jmxserviceurl URL = new Jmxserviceurl (connectoraddress); Jmxserviceurl url = new JMXserviceurl ("Service:jmx:rmi:///jndi/rmi://localhost:1099/testjmxserver");
Connector = jmxconnectorfactory.connect (URL);
Mbeanserverconnection mbeanconn = Connector.getmbeanserverconnection ();
set<objectname> beanset = mbeanconn.querynames (null, NULL); // ...
}
catch (Exception e) {e.printstacktrace ();
Finally {try {if (Connector!= null) Connector.close ();
Break
catch (IOException e) {//TODO auto-generated catch block E.printstacktrace (); }
}
}
}
It should be noted that the code above needs to put Tools.jar into the classpath.
The code above sometimes does not get the local connection address, this time need to try to let the agent load Management-agent.jar, the complete code is as follows:
Package Cn.myroute.mbean;
Import Java.io.File;
Import java.io.IOException;
Import Java.lang.reflect.Method;
Import Java.net.URL;
Import Java.net.URLClassLoader;
Import java.util.List;
Import java.util.Properties; public class Abstractjmxcommand {private static final String connector_address = "Com.sun.management.jmxremo
Te.localconnectoraddress ";
public static String GETJVM () {return System.getproperty ("Java.vm.specification.vendor");
public static Boolean ISSUNJVM () {//need to check for Oracle as this is the name for Java7 onwards. return GETJVM () equals ("Sun Microsystems Inc.") | |
GETJVM (). StartsWith ("Oracle"); public static void Main (string[] args) {if (args = null | | args.length = = 0) {System.out.println ("Usage
: pid ");
Return
int pid =integer.valueof (args[0]);
System.out.println (New Abstractjmxcommand (). FINDJMXURLBYPROCESSID (PID)); }/** * finds the JMX Url for a VM by its proceSS ID * * @param PID * The process ID value of the VM to search for.
* * @return The JMX Url of the VM with the given PID or null if not found. *//@SuppressWarnings ({"Rawtypes", "Unchecked"}) protected String findjmxurlbyprocessid (int pid) {if (ISSUNJVM ())
{try {//Classes are all dynamically loaded, since they are specific to Sun VM If it fails for any reason default JMX URL would be used//Tools.jar are not always included used B
Y default class loader, so we/would try to use custom loader that'll try to load Tools.jar
String javahome = System.getproperty ("Java.home"); String tools = javahome + File.separator + "..." + file.separator + "Lib" + File.separator + "Tools"
. Jar ";
URLClassLoader loader = new URLClassLoader (new Url[]{new File (Tools). Touri (). Tourl ()});Class virtualmachine = Class.forName ("Com.sun.tools.attach.VirtualMachine", true, loader);
Class virtualmachinedescriptor = Class.forName ("Com.sun.tools.attach.VirtualMachineDescriptor", true, loader);
Method getvmlist = Virtualmachine.getmethod ("list", (class[]) null);
Method ATTACHTOVM = Virtualmachine.getmethod ("Attach", string.class);
Method getagentproperties = Virtualmachine.getmethod ("Getagentproperties", (class[)) null);
Method Getvmid = Virtualmachinedescriptor.getmethod ("id", (class[]) null);
List Allvms = (list) Getvmlist.invoke (null, (object[)) null);
for (Object Vminstance:allvms) {String id = (string) Getvmid.invoke (Vminstance, (object[)) null);
if (Id.equals (integer.tostring (PID)) {Object VM = Attachtovm.invoke (null, ID); Properties Agentproperties = (properties) getagentpRoperties.invoke (VM, (object[]) null);
String connectoraddress = Agentproperties.getproperty (connector_address);
if (connectoraddress!= null) {return connectoraddress;
} else {break;
The attempt to get the agent to load the Management-agent.jar is unsuccessful.
Method getsystemproperties = Virtualmachine.getmethod ("Getsystemproperties", (class[)) null);
Method loadagent = Virtualmachine.getmethod ("Loadagent", String.class, String.class);
Method detach = Virtualmachine.getmethod ("Detach", (class[)) null);
for (Object Vminstance:allvms) {String id = (string) Getvmid.invoke (Vminstance, (object[)) null); if (Id.equals (integer.tostring (PID)) {Object VM = Attachtovm.invoke (NULL, ID);
Properties Systemproperties = (properties) Getsystemproperties.invoke (VM, (object[)) null);
String home = Systemproperties.getproperty ("Java.home"); Normally in ${java.home}/jre/lib/management-agent.jar but might//is in ${java.home}/lib in BU
ILD environments. String Agent = home + file.separator + "JRE" + file.separator + "Lib" + file.se
Parator + "Management-agent.jar";
File F = new file (agent);
if (!f.exists ()) {Agent = home + file.separator + "Lib" + File.separator +
"Management-agent.jar";
f = new File (agent); if (!f.exists ()) {throw new IOException ("Management Agent not Found");
} Agent = F.getcan
Onicalpath ();
Loadagent.invoke (VM, Agent, "Com.sun.management.jmxremote");
Properties Agentproperties = (properties) Getagentproperties.invoke (VM, (object[)) null);
String connectoraddress = Agentproperties.getproperty (connector_address);
Detach this VM Detach.invoke (VM, (object[]) null);
if (connectoraddress!= null) {return connectoraddress;
} else {break;
catch (Exception ignore) {ignore.printstacktrace ();
} return null; }
}
2. Remote connection There is no doubt that if you want to access remotely, you will definitely need to register one or more ports, such as RMI Port, HTTP port, and so on Mbeanserver.
There are two ways to register and access the 2.1 RMI Port , one that specifies the RMI port directly inside the code and is bound, such as the following, this method needs to be accessed using client connection code, and the other code does not specify a port. It is necessary to register the Mbean inside the Platformmbeanserver and specify the JMX parameter when starting the process, which can be accessed remotely via JCONSOLE,JVISUALVM. 2.1.1 Bind ports directly inside the code
@Test public void Testjmxrmiregist () throws Exception {int rmiport = 2222;
String jmxservername = "cn.myroute.mbean.mm";
Jdkfolder/bin/rmiregistry.exe 9999 Registry Registry = Locateregistry.createregistry (Rmiport);
Mbeanserver mbs = Mbeanserverfactory.creatembeanserver (jmxservername);
SYSTEM.OUT.PRINTLN (MBS);
MBS = Mbeanserverfactory.creatembeanserver ();
Creates a new Mbean objectname that identifies the registered Mbean objectname name = new ObjectName (jmxservername + ": Type=echo") in Mbeanserver;
Htmladaptorserver adapter = new Htmladaptorserver ();
Create Mbean echo Mbean = new echo ();
Registers an Mbean in the mbeanserver, identified as ObjectName (Com.tenpay.jmx:type=echo) Mbs.registermbean (Mbean, name);
Jmxserviceurl url = new Jmxserviceurl ("Service:jmx:rmi:///jndi/rmi://localhost:" + rmiport + "/" + jmxservername);
System.out.println ("Jmxserviceurl:" + url.tostring ());
Jmxconnectorserver jmxconnserver = jmxconnectorserverfactory.newjmxconnectorserver (URL, null, MBS);
Jmxconnserver.start ();
Thread.Sleep (1000 * 60 * 10); }
The above program is a new mbeanserver and is bound to port 2222 via RMI, waiting for the client to connect.
2.1.2 Start a process with the JMX parameter#JVMARGS = "$JVMARGS-dcom.sun.management.jmxremote.port=8888-dcom.sun.management.jmxremote.ssl=false- Dcom.sun.management.jmxremote.authenticate=false "
By this process of JMX monitoring binding to the specified port, can be remote through the jconsole monitoring.
2.2 access via HTTP
@Test public
void Testjmxhtmladapter () throws Exception {
String jmxservername = "cn.myroute.mbean.mm";
Jdkfolder/bin/rmiregistry.exe 9999
Mbeanserver mbs = Mbeanserverfactory.creatembeanserver (jmxServerName);
SYSTEM.OUT.PRINTLN (MBS);
MBS = Mbeanserverfactory.creatembeanserver ();
Creates a new Mbean objectname that identifies the registered Mbean
objectname name = new ObjectName (jmxservername + ": Type=echo") in Mbeanserver;
Htmladaptorserver adapter = new Htmladaptorserver ();
Create Mbean
echo Mbean = new Echo ();
Registers an Mbean in the mbeanserver, identified as ObjectName (Com.tenpay.jmx:type=echo)
Mbs.registermbean (Mbean, name);
Htmladaptorserver adapter = new Htmladaptorserver ();
ObjectName AdapterName;
AdapterName = new ObjectName (jmxservername + ": name=" + "Htmladapter");
Adapter.setport (8082);
Adapter.start ();
Mbs.registermbean (adapter, adaptername);
Thread.Sleep (1000 *);
}
The above code used to htmladaptorserver, need to download jjmx-1_2_1-ri.zip, put inside Jmxtools.jar add classpath inside, download address: http://java.sun.com/products /javamanagement/download.html.
Then you can access it in the browser
3. Client Connection
@Test public
void Test1 () {
try {
jmxserviceurl url = new Jmxserviceurl ("service:jmx:rmi:///jndi/rmi:// LOCALHOST:2222/CN.MYROUTE.MBEAN.MM ");
Jmxconnector connector = jmxconnectorfactory.connect (URL);
Mbeanserverconnection mbeanconn = Connector.getmbeanserverconnection ();
set<objectname> beanset = mbeanconn.querynames (null, NULL);
System.out.println (Beanset);
} catch (Exception e) {
//TODO auto-generated catch block
e.printstacktrace ();
}
}
4. Java Process Self-brought MbeanWhen we are monitoring Java processes with Jconsole and JVISUALVM, we usually see usage of CPU, memory, thread, garbage collection, etc., and the data is actually taken from some of the mbean provided by the JVM through JMX. Mainly as follows:
Classloadingmxbean
Classloadmxbean includes the loading information for some classes, such as how many classes have been loaded/unloaded (unloaded), whether the verbose option that the virtual machine class mounts (that is, the Java–verbose:class option on the command line) is turned on, and can also help the user turn on/off Close this option. Compilationmxbean
Compilationmxbean helps users understand the current compiler and compilation situation, the Mxbean provides little information. Garbagecollectormxbean
The information provided by the Mxbean is very limited relative to the extent to which the open person is concerned with GC, providing only the number of GC and the approximate amount of time the GC spends. However, this package also provides three memory management detection classes: Memorymanagermxbean,memorymxbean and Memorypoolmxbean. Memorymanagermxbean
This class is relatively simple and provides name information for memory management classes and memory pools (memory pool). Memorymxbean
This class provides memory usage across the entire virtual machine, including memory consumed by the Java heap (heap) and non-Java heaps, providing the number of objects currently waiting for finalize, and it can even do GC (actually call SYSTEM.GC). Memorypoolmxbean
This information provides a great deal of information. In the JVM, there may be several memory pools, so there is the corresponding memory pool information, so in the factory class, Getmemorypoolmxbean () is given a memorypoolmxbean list. Each memorypoolmxbean contains detailed information about the memory pool, such as availability, current memory/maximum memory value, and setting maximum memory values, and so on. Operatingsystemmxbean
This class provides simple information about the operating system, such as the schema name, the current number of CPUs, the most recent system load, and so on. Runtimemxbean
The Run-time information includes the name, provider, version number of the current virtual machine, classpath, Bootclasspath, and system parameters, and so on. Threadmxbean
In Java, a multithreaded system, the monitoring of threads is very important. Threadmxbean is the only way to play this role. The information that Threadmxbean can provide includes the various states of each thread, the CPU footprint, and the threading condition throughout the system. The Threadinfo object of a thread can be obtained from the Threadmxbean. This object contains all of the information for this thread.
To get this information, we first get a series of MXBean by java.lang.management.ManagementFactory this factory class.
Classloadingmxbean mbs = Managementfactory.getclassloadingmxbean ();
System.out.println ("Loadedclass:" + mbs.getloadedclasscount ());