博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring JMX之二:远程访问MBean
阅读量:6512 次
发布时间:2019-06-24

本文共 7728 字,大约阅读时间需要 25 分钟。

虽然最初的JMX规范提及了通过MBean进行应用的远程管理,但是它并没有定义实际的远程 访问协议或API。因此,会由JMX供应商定义自己的JMX远程访问解决方案,但这通常又是专 有的。

为了满足以标准方式进行远程访问JMX的需求,JCP(Java Community Process)制订了JSR-160: Java管理扩展远程访问API规范(Java Management Extensions Remote API Specification)。该规范 定义了JMX远程访问的标准,该标准至少需要绑定RMI和可选的JMX消息协议(JMX Messaging Protocol ,JMXMP)。

在本小节中,我们将看到Spring如何远程访问MBean。我们首先从配置Spring把 SpittleController导出为远程MBean开始,然后我们再了解如何使用Spring远程操纵 MBean。

1、暴露远程MBean

使MBean成为远程对象的最简单方式是配置Spring的ConnectorServerFactoryBean:

@Bean    public ConnectorServerFactoryBean connectorServerFactoryBean() {        return new ConnectorServerFactoryBean();    }

ConnectorServerFactoryBean会创建和启动JSR-160 JMXConnectorServer。默认 情况下,服务器使用JMXMP协议并监听端口9875——因此,它将绑 定“service:jmx:jmxmp://localhost:9875”。但是我们导出MBean的可选方案并不局限于JMXMP。

根据不同JMX的实现,我们有多种远程访问协议可供选择,包括远程方法调用(Remote Method Invocation,RMI)、SOAP、Hessian/Burlap和IIOP(Internet InterORB Protocol)。为MBean绑定不同 的远程访问协议,我们仅需要设置ConnectorServerFactoryBean的serviceUrl属性。 例如,如果我们想使用RMI远程访问MBean,我们可以像下面示例这样配置:

@Bean    public ConnectorServerFactoryBean connectorServerFactoryBean() {        ConnectorServerFactoryBean csfb = new ConnectorServerFactoryBean();        csfb.setServiceUrl("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/spitter");        return csfb;    }

在这里,我们将ConnectorServerFactoryBean绑定到了一个RMI注册表,该注册表监听 本机的1099端口。这意味着我们需要一个RMI注册表运行时,并监听该端口。我们可以回顾下第15章,RmiServiceExporter可以为我们自动启动一个RMI注册表。但是,我们在本示例 中不使用RmiServiceExporter,而是通过在Spring中声明RmiRegistryFactoryBean 来启动一个RMI注册表,如下面的@Bean方法所示:

@Bean    public RmiRegistryFactoryBean rmiRegistryFB() {        RmiRegistryFactoryBean rmiRegistryFB = new RmiRegistryFactoryBean();        rmiRegistryFB.setPort(1099);        return rmiRegistryFB;    }

没错!现在我们的MBean可以通过RMI进行远程访问了。

完整代码如下:

package com.dxz.mvcdemo1.web.jmx4;import static org.springframework.web.bind.annotation.RequestMethod.GET;import org.springframework.context.annotation.Bean;import org.springframework.jmx.export.annotation.ManagedAttribute;import org.springframework.jmx.export.annotation.ManagedResource;import org.springframework.jmx.support.ConnectorServerFactoryBean;import org.springframework.remoting.rmi.RmiRegistryFactoryBean;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controller@RequestMapping("/biz4")@ManagedResource(objectName="spitter:name=SpittleController4") //将SpittleController导出为MBeanpublic class SpittleCntroller4 {    // 默认每个页面的大小    public static final int DEFAULT_SPITTLES_PER_PAGE = 25;    // 每页的大小    private int spittlesPerPage = DEFAULT_SPITTLES_PER_PAGE;    //@ManagedOperation@ManagedOperation注解替换@ManagedAttribute注解来标注存取器方法    @ManagedAttribute        //将spittlesPerPage暴露为托管属性    public int getSpittlesPerPage() {        return spittlesPerPage;    }        //@ManagedOperation@ManagedOperation注解替换@ManagedAttribute注解来标注存取器方法    @ManagedAttribute        //将spittlesPerPage暴露为托管属性    public void setSpittlesPerPage(int spittlesPerPage) {        this.spittlesPerPage = spittlesPerPage;    }    @RequestMapping(value = "/test4", method = GET)    public String test() {        String result = spittlesPerPage + " - test()";        System.out.println(result);        return "home";    }    //启动一个RMI注册表,并监听1099端口    @Bean    public RmiRegistryFactoryBean rmiRegistryFB() {        RmiRegistryFactoryBean rmiRegistryFB = new RmiRegistryFactoryBean();        rmiRegistryFB.setPort(1099);        return rmiRegistryFB;    }        //将ConnectorServerFactoryBean绑定到了上面的RMI注册表,该注册表监听本机的1099端口    @Bean    public ConnectorServerFactoryBean connectorServerFactoryBean() {        ConnectorServerFactoryBean csfb = new ConnectorServerFactoryBean();        csfb.setServiceUrl("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/spitter");        return csfb;    }}

启动测试:

注意:日志中RMI注册表运行了,并监听1099端口

下面先通过java自带的工具连接及测试如下,选择“远程进程”并将代码中的url=“service:jmx:rmi://localhost/jndi/rmi://localhost:1099/spitter”填入输入框中,进行连接:

连接成功后的结果如下:

但是如果没有人通过RMI访问MBean 的话,那就不值得这么做。所以现在让我们把关注点转向JMX远程访问的客户端,看看如何在 Spring中装配一个远程MBean到JMX客户端中。

2 访问远程MBean

要想访问远程MBean服务器,我们需要在Spring上下文中配置MbeanServerConnectionFactoryBean。下面的bean声明装配了一个MbeanServerConnectionFactoryBean,该bean用于访问我们在上一节中所创建的基于RMI的远程服务器。

@Bean    public MBeanServerConnectionFactoryBean connectionFactoryBean() throws MalformedURLException {        MBeanServerConnectionFactoryBean mbscfb = new MBeanServerConnectionFactoryBean();        mbscfb.setServiceUrl("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/spitter");        return mbscfb;    }

顾名思义,MBeanServerConnectionFactoryBean是一个可用于创建MbeanServerConnection的工厂bean。由MBeanServerConnectionFactoryBean所生成的 MBeanServerConnection实际上是作为远程MBean服务器的本地代理。它能够以 MBeanServerConnection的形式注入到其他bean的属性中:

@Bean    public JmxClient jmxClient(MBeanServerConnection connection) {        JmxClient jmxClient = new JmxClient();        jmxClient.setMbeanServerConnection(connection);        return jmxClient;    }

JmxClient.java

package com.dxz.mvcdemo2.web;import javax.management.MBeanServerConnection;import org.springframework.stereotype.Component;@Componentpublic class JmxClient {    MBeanServerConnection mbeanServerConnection;        public JmxClient() {            }        public MBeanServerConnection getMbeanServerConnection() {        return mbeanServerConnection;    }    public void setMbeanServerConnection(MBeanServerConnection mbeanServerConnection) {        this.mbeanServerConnection = mbeanServerConnection;    }

测试类:

package com.dxz.mvcdemo2.web;import static org.springframework.web.bind.annotation.RequestMethod.GET;import java.io.IOException;import java.net.MalformedURLException;import java.util.Set;import javax.management.AttributeNotFoundException;import javax.management.InstanceNotFoundException;import javax.management.MBeanException;import javax.management.MBeanServerConnection;import javax.management.MalformedObjectNameException;import javax.management.ObjectName;import javax.management.ReflectionException;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.jmx.support.MBeanServerConnectionFactoryBean;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controller@RequestMapping("/biz4")public class ClientController {    @Autowired    JmxClient jmxClient;    @RequestMapping(value = "/client4", method = GET)    public String test() throws IOException, MalformedObjectNameException, AttributeNotFoundException,            InstanceNotFoundException, MBeanException, ReflectionException {        MBeanServerConnection connection = jmxClient.mbeanServerConnection;        int mbenaCount = connection.getMBeanCount();        System.out.println("There are " + mbenaCount + " MBeans");        ObjectName managerObjName = new ObjectName("spitter:name=SpittleController4");        Set
s = connection.queryNames(managerObjName, null); for (ObjectName obj : s) { System.out.println(obj); } Object cronExpression = connection.getAttribute(new ObjectName("spitter:name=SpittleController4"), "SpittlesPerPage"); System.out.println(cronExpression); return "home"; } @Bean public MBeanServerConnectionFactoryBean connectionFactoryBean() throws MalformedURLException { MBeanServerConnectionFactoryBean mbscfb = new MBeanServerConnectionFactoryBean(); mbscfb.setServiceUrl("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/spitter"); return mbscfb; } @Bean public JmxClient jmxClient(MBeanServerConnection connection) { JmxClient jmxClient = new JmxClient(); jmxClient.setMbeanServerConnection(connection); return jmxClient; }}

结果:

3、代理MBean

转载地址:http://vgifo.baihongyu.com/

你可能感兴趣的文章
字符串的相关操作
查看>>
oracle的group by问题
查看>>
为什么一般请求可以下载文件,Ajax 请求就不能下载
查看>>
nodejs安装与配置+初学实例详解
查看>>
在Mac上用自己编译出的DNX运行.NET程序
查看>>
简单的自我介绍
查看>>
XPath学习
查看>>
SQL的索引语句
查看>>
Android AndroidRuntime类
查看>>
动态引用样式表
查看>>
面试题:求最长非重复子序列
查看>>
实验四主存空间的分配和回收
查看>>
mysql中导入txt文件
查看>>
spring注入时bean的set方法为什么不能是static类型的?
查看>>
tar 报错gzip: stdin: not in gzip format
查看>>
Kubernetes init container
查看>>
区块链圈测试需要掌握的技能点汇总
查看>>
自定义拦截器
查看>>
实验 7 流类库 与输入输出
查看>>
html5表单
查看>>