JMX本地通信

2023-10-05  本文已影响0人  ntjsz

场景

使用 jconsole visualvm jmc等工具连接本地的 java 进程时,会使用 jmx 的通信机制进行通信。

通信方式

以下样例代码解释了 jmx 通信的核心流程

// 1. 获取所有 java 进程
List<VirtualMachineDescriptor> list = VirtualMachine.list();

int index = 0;
VirtualMachine vm = VirtualMachine.attach(list.get(index));

// 2. 获取 jmx 通信地址
Properties props = vm.getAgentProperties();
String connectorAddress = props.getProperty("com.sun.management.jmxremote.localConnectorAddress");
JMXServiceURL url = new JMXServiceURL(connectorAddress);
JMXConnector jmxConnector = JMXConnectorFactory.connect(url);

// 3. 远程方法调用
MBeanServerConnection mbsc = jmxConnector.getMBeanServerConnection();
String result = (String) mbsc.invoke(new ObjectName("objectName"), "functionName", new Object[]{}, new String[]{});

1. 获取所有 java 进程

类似于 jps 的功能,借助于 hsperfdata 文件获取所有 java 进程的pid

每个java进程启动时,都会在系统的临时文件目录下创建一个以pid为文件名的hsperfdata文件。这个目录下的所有文件代表了所有 java 进程的 pid。

假设用户名为 userabcd,pid 为 1234,实际文件名如下

2. 获取 jmx 通信地址

使用进程间通信获取 agentProperties,从agentProperties中获取com.sun.management.jmxremote.localConnectorAddress key,即为 jmx 通信地址

进程间通信的方式

通过进程间通信,向 jvm 发送 agentProperties 命令,jvm回复的属性中包含了jmx 通信地址,地址格式如下
service:jmx:rmi://127.0.0.1/stub/{base64}

3. 远程方法调用

jmx 通信地址中包含了使用哪种通信协议,jndi或是jrmp
例如 jmx 通信地址
service:jmx:rmi://127.0.0.1/stub/{base64}
中的 stub 代表 jrmp 协议,之后的 {base64} 编码字符串中包含了用于 jrmp 协议通信的 host 和 port。
至此,可以使用 jrmp 协议进行通信(远程方法调用)

上一篇 下一篇

猜你喜欢

热点阅读