Java JMX客户端示例– JMX身份验证

时间:2020-02-23 14:34:29  来源:igfitidea点击:

我们了解了JMX Basics,以及如何使用JConsole管理MBean。
今天,我们将通过配置文件研究java jmx客户端示例和基于角色的身份验证。

Java JMX客户端

尽管JConsole提供了图形化视图,但是使用MBean需要人工操作,因此不适合需要定期调用MBean某些功能的地方。
例如,您有一个MBean提供了应用程序的当前状态,并且您想调用它以每10分钟检查一次状态。
在这种情况下,拥有一个可用作JMX Client的Java程序以连接到JMX MBean服务器并调用MBean操作非常有用。

JMX客户端示例

其中我们将编写一个Java程序,该程序可以连接到MBean服务器并创建代理应用程序以调用MBean操作。
我将使用JMX教程中创建的MBean应用程序,并使用我们的客户端程序连接到MBean。
稍后,我们将检查如何使用JMX配置文件使MBean服务器安全以进行基于角色的访问,以及如何使用JMX Client中的凭据以正确的角色连接到MBean服务器。

在编写JMX Client应用程序之前,我们需要知道MBean服务器运行的端口。
同样对于,我们将禁用所有身份验证。
我们可以通过传递正确的java选项来完成所有这些操作。

因此,我将使用以下命令启动我的MBean。
请注意,为MBean服务器端口指定了java选项,并禁用了SSL和身份验证。

hyman@JD:~/CODE/JavaProject/bin$java -cp . -Dcom.sun.management.jmxremote.port=1234 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false com.theitroad.jmx.SystemConfigManagement
Thread Count=10:::Schema Name=default
Thread Count=10:::Schema Name=default
Thread Count=10:::Schema Name=default
...

JMX URL

为了使客户端应用程序获得MBean代理,首先我们需要通过传递RMI主机和端口来创建JMXServiceURL

JMXServiceURL url =
          new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + HOST + ":" + PORT + "/jmxrmi");

之后,我们必须使用工厂类来获取" JMXConnector"实例。

JMXConnector jmxConnector = JMXConnectorFactory.connect(url);

之后,我们从JMXConnector实例获得MBeanServerConnection

MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();

之后,我们使用MBeanServerInvocationHandler获取MBean代理实例。

//ObjectName should be same as your MBean name
ObjectName mbeanName = new ObjectName("com.theitroad.jmx:type=SystemConfig");

//Get MBean proxy instance that will be used to make calls to registered MBean
SystemConfigMBean mbeanProxy =
  (SystemConfigMBean) MBeanServerInvocationHandler.newProxyInstance(
      mbeanServerConnection, mbeanName, SystemConfigMBean.class, true);

一旦获得代理实例,就可以调用MBean公开的任何操作。

Java JMX客户端示例程序

这是连接到MBean服务器并获取SystemConfig MBean代理实例并调用公开方法的完整JMX Client程序。

package com.theitroad.jmx;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class SystemConfigClient {

  public static final String HOST = "localhost";
  public static final String PORT = "1234";

  public static void main(String[] args) throws IOException, MalformedObjectNameException {
      JMXServiceURL url =
          new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + HOST + ":" + PORT + "/jmxrmi");
      
      JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
      MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();
      //ObjectName should be same as your MBean name
      ObjectName mbeanName = new ObjectName("com.theitroad.jmx:type=SystemConfig");

      //Get MBean proxy instance that will be used to make calls to registered MBean
      SystemConfigMBean mbeanProxy =
          (SystemConfigMBean) MBeanServerInvocationHandler.newProxyInstance(
              mbeanServerConnection, mbeanName, SystemConfigMBean.class, true);

      //let's make some calls to mbean through proxy and see the results.
      System.out.println("Current SystemConfig::" + mbeanProxy.doConfig());
      
      mbeanProxy.setSchemaName("NewSchema");
      mbeanProxy.setThreadCount(5);
      
      System.out.println("New SystemConfig::" + mbeanProxy.doConfig());
      
      //let's terminate the mbean by making thread count as 0
      mbeanProxy.setThreadCount(0);

      //close the connection
      jmxConnector.close();
  }
}

在运行客户端应用程序之前,请确保我们的MBean应用程序已使用发布开始时给出的命令启动。
当我们执行客户端应用程序时,它将打印以下内容到控制台。

Current SystemConfig::No of Threads=10 and DB Schema Name=default
New SystemConfig::No of Threads=5 and DB Schema Name=NewSchema

如果您要检查运行我们的MBean应用程序的终端,您将在程序终止之前找到以下输出。

Thread Count=10:::Schema Name=default
Thread Count=10:::Schema Name=default
Thread Count=0:::Schema Name=NewSchema

因此,现在我们知道如何编写可以连接到远程MBean服务器的JMX客户端程序,并创建MBean代理以使用MBean公开的属性和操作。

基于JMX角色的身份验证

让我们开始为基于角色的身份验证配置MBean。
为此,我们需要创建三个文件。

  • JMX访问文件:此文件包含角色和与角色相关联的访问。
    访问类型为"只读"或者"读写"。
    为此,请创建具有以下内容的" jmxremote.access"文件。

因此,角色是" myrole",它具有对MBean的读写访问权限。

  • JMX密码文件:该文件包含我们拥有的不同角色的密码,密码为明文,因此Java添加了一个限制,即只有应用程序所有者才能对该文件具有读写访问权限。
    创建文件jmxremote.password并添加以下内容内容。
    jmxremote.password

创建文件后,使用命令" chmod 600 jmxremote.password"更改权限。

  • JMX管理配置文件:此文件包含JMX属性,例如端口,身份验证规则,SSL等。
    创建具有以下内容的文件" management.properties"。

注意为访问文件和密码文件指定的文件路径。

完成所有必需的文件后,我们将使用以下命令启动JMX MBean应用程序。

myrole readwrite

现在,如果您尝试运行我们的JMX Client应用程序,它将引发以下异常。

myrole MYP@SSWORD

异常消息清楚地表明,我们需要提供凭据才能访问JMX MBean。
为了提供凭据,我们需要在客户端程序中添加以下代码。

#enable remote management of MBean
com.sun.management.jmxremote=true
com.sun.management.jmxremote.port=1234
com.sun.management.jmxremote.local.only=false

#enable authentication
com.sun.management.jmxremote.authenticate=true
com.sun.management.jmxremote.password.file=/Users/hyman/CODE/JavaProject/bin/jmxremote.password
com.sun.management.jmxremote.access.file=/Users/hyman/CODE/JavaProject/bin/jmxremote.access

#disable SSL authentication
com.sun.management.jmxremote.ssl=false

注意,连接到JMX MBean服务器时,构造函数已更改为提供凭据。