不是吧,JMX啥你都不知道?

JMX简介

在Java程序中,我们常常需要对JVM和系统进行检测,在以前,开发人员必须通过一些底层的 JVM API,比如 JVMPI 和 JVMTI 等,才能监测 Java 程序运行过程中的一系列情况,但是这种需要大量的 C 程序和 JNI 调用,开发效率十分低下,为了解决这个问题,Sun 公司也在其 Java SE 5 版本中,正式提出了 Java 管理扩展(Java Management Extensions,JMX)用来管理检测 Java 程序,同时 JMX 也在 J2EE 1.4 中被发布。

MBean、MBeanServer

MBean是Managed Bean的简称。在JMX中MBean代表一个被管理的资源实例,通过MBean中暴露的方法和属性,外界可以获取被管理的资源的状态和操纵MBean的行为。

MBean在一个MBeanServer中。MBeanServer管理这些MBean,并且代理外界对它们的访问。并且MBeanServer提供了一种注册机制,外界可以通过名字来得到相应的MBean实例。

创建MBean时,必须遵循一种特定的设计模式。模型MBean类必须实现一个具有以下名称的接口:“模型类名称”加MBean。

代码实例

public interface TestMBean {
    public void close();

    public void start();

    public void change(String name);
}


public class Test implements TestMBean {
    @Override
    public void close() {
        System.out.println("关闭");
    }

    @Override
    public void start() {
        System.out.println("打开");
    }

    @Override
    public void change(String name) {
        System.out.println("改变-------》"+name);
    }
}

首先我们需要将MBean实现注册到MBean服务器,注册MBean之后,为了能够对其进行测试,需要添加一个死循环以防止应用程序终止,然后才能通过JConsole访问MBean。

ObjectName表示一个MBean的对象名称。


public class Main {
    public static void main(String[] args) {
        try {
            ObjectName objectName = new ObjectName("com.baeldung.tutorial:type=basic,name=game");
            MBeanServer server = ManagementFactory.getPlatformMBeanServer();
            server.registerMBean(new Test(), objectName);
        } catch (MalformedObjectNameException | InstanceAlreadyExistsException |
                MBeanRegistrationException | NotCompliantMBeanException e) {
            // handle exceptions
        }

        for(;;){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

要启动JConsole,可以打开一个终端窗口并运行jconsole命令,这个程序在JDK_HOME/bin下。

JConsole允许创建本地连接以及与远程进程的连接,我们可以在本地进程列表中看到我们的程序名称。只需选择应用程序并单击“连接”按钮,连接后转到MBean选项卡,我们就可以动态更改的值。

在这里插入图片描述在这里插入图片描述

客户端示例

虽然JConsole提供了图形化界面操作,但是有些地方就不太合适使用,比如我们需要定期调用MBean的某些功能,每10分钟检查一次状态。在这种情况下,我们需要自己编写一个连接到JMX MBean服务器并调用MBean操作的操作。

以下代码启动MBean服务器,端口为9696,并禁用了SSL和身份验证。

public class Main {
    private static int PORT=9696;

    public static void main(String[] args) {
        try {

            ObjectName objectName = new ObjectName("com.hxl.jmx:type=basic,name=hxl");
            MBeanServer server = ManagementFactory.getPlatformMBeanServer();
            server.registerMBean(new Test(), objectName);
            LocateRegistry.createRegistry(PORT);

            JMXServiceURL url = new JMXServiceURL
                    ("service:jmx:rmi:///jndi/rmi://localhost:"+PORT+"/jmxrmi");
            JMXConnectorServer jcs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);


            jcs.start();
        } catch (Exception e) {
        }
        for(;;){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

上面这段还可以通过启动参数来控制,不需要编写代码,但如果同时存在的话,两个端口貌似是都可以使用。

-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

下面是客户端,大概三步。

  1. 创建JMXServiceURL,给他传递RMI主机和端口,所有的JMX URL都必须以“service:jmx”开头,否则会抛MalformedURLException。

  2. 通过JMXConnectorFactory获取一个JMXConnector实

  3. 通过MBeanServerInvocationHandler返回TestMBean代理

public class ClientTest {
    private static final String HOST="127.0.0.1";
    private static int PORT=9696;

    public static void main(String[] args) {

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

			//之后,我们必须使用JMXConnector工厂类来获取实例。
            JMXConnector jmxConnector = JMXConnectorFactory.connect(url);


            MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();
            ObjectName mbeanName = new ObjectName("com.hxl.jmx:type=basic,name=hxl");

			//获取代理,如果获得代理成功,就可以调用MBean公开的任何操作。
            TestMBean mbeanProxy =
                    (TestMBean) MBeanServerInvocationHandler.newProxyInstance(
                            mbeanServerConnection, mbeanName, TestMBean.class, true);
            mbeanProxy.start();
            mbeanProxy.change("test");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MalformedObjectNameException e) {
            e.printStackTrace();
        }
    }
}

运行之后控制台会输出如下:
在这里插入图片描述

Tomcat JMX

首先需要在catalina.sh中配置开启JMX,Windows为catalina.bat,以下在Linux中演示,在catalina.sh中加入以下参数即可,端口可以随意更改,但是注意需要在一行。

CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

在这里插入图片描述
通过./catalina.sh run运行Tomcat,在JConsole中选中远程连接,输入127.0.0.1:9999进行连接。
在这里插入图片描述

以下演示停止、启动某个项目。

选中最右侧的MBean选项卡,接着展开WebModule。
在这里插入图片描述
选中某个要停止的项目后,点击"操作"-----stop(),即可停止项目。
在这里插入图片描述
停止后无法在访问,相反,点击start()可以重新启动。

在这里插入图片描述
基于这个,我们可以自己做一套Tomcat管理软件。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值