Jmx 资源管理——demo篇
2017-11-17 10:30
232 查看
什么是Jmx
全称Java Management Extensions,可以将之理解为管理java资源的一个服务。当你运行一个java程序时,你可以通过它来掌握运行期间一些资源的情况,还可以在运行期间动态修改某些资源的值。Jmx架构
至于Jmx的结构,可以参考下面这张图:看起来挺复杂,不过没关系,一点一点来。
整体分三层:
- 最下层是资源层,也就是你要管理的资源,一般就是一个普通的java bean,包含你要管理的属性,以及你要进行的操作。只不过Jmx规定这些资源类要叫做XXXMBean,反正是要让Jmx认出来。
- 中间是代理层,你对于下面资源的操作都要通过代理层进行。这个很常见,许多java应用或者框架的结构都是这样,通过统一的代理进行操作,结构清晰,便于管理。
- 最上层是管理层,其实叫做管理层不太合适,因为这一层并不是直接管理资源,上文已经说过要通过代理层访问,因此这一层只不过给我们提供了连接代理层的方式。为了可以通过多种方式访问资源,如web端,控制台,或者通过编程API自己编写客户端,就需要对于不同的方式提供不同的适配器或连接器,如上图所示。
一个简单的demo
说了那么多,不如自己写一个简单的demo,理解更深刻。首先要创建你要管理的资源,Jmx中一般是一个java bean,但是为了与一般的bean做区分,Jmx中的资源要实现以MBean为后缀的接口。几行代码,创建一个简单的MBean资源,如下:
public interface HelloWorldMBean { String getHelloWorld(); void setHelloWorld(String hello); } public class HelloWorld implements HelloWorldMBean { private String helloWorld; @Override public String getHelloWorld() { return helloWorld; } @Override public void setHelloWorld(String helloWorld) { this.helloWorld = helloWorld; } }
上面是一个以MBean为后缀的接口,下面是其实现类,也就是我们所说的Jmx中的资源。其实就跟一个普通的java bean差不多,除了命名需要遵守特定的规则,其他没什么不同(至于为什么需要这样命名,后文讨论)。此外,如果你想查询属性,则要设置get方法;需要修改属性,需要设置set方法。(此部分内容也在后文讨论)。
资源写好了,按照架构图,应该给它找个代理。仍旧几行代码,如下:
// get a default MBean server MBeanServer server = ManagementFactory.getPlatformMBeanServer(); // the name of MBean ObjectName mbeanName = new ObjectName("hello:name=HelloWorld"); // instance of helloWorldMBean and register HelloWorldMBean helloWorldMBean = new HelloWorld(); // register MBean to server server.registerMBean(helloWorldMBean, mbeanName);
配合着注释,简单解释就是,创建了一个供MBean注册的server,然后创建一个资源类的实例,将其注册上去。
不过有意思的是,代码中有个ObjectName,你可以把它当作你注册MBean时的代号。很简单,有许多资源要往你的server上注册,你要区分不同的MBean,就得有个代号,就是这个ObjectName。
创建ObjectName时,需要注意你传递的字符串需要遵从特定的格式,简单来说就是 {域名}:{key1}={value1},{key2}={value2}…{keyn}={valuen}。其实这个规则比较复杂,后文再讨论。
注册完了,如何使用呢? 很简单的几行代码,如下:
// get attribute String helloWorld = (String) server.getAttribute(mbeanName, "HelloWorld"); System.out.println(helloWorld);//print null // set attribute server.setAttribute(mbeanName, new Attribute("HelloWorld", "hey")); // get attribute after changing helloWorld = (String) server.getAttribute(mbeanName, "HelloWorld"); System.out.println(helloWorld);//print hey
可以发现,将MBean注册到server之后,你只需通过ObjectName和属性名,就能修改和查询MBean中的属性值。(前提是你的MBean中有相应的set和get方法)
简单的demo这样就没了。。。好像没什么用啊, 如果只是更改bean的属性,那么我们直接调用set和get方法不是也可以吗?接下来我们试下用浏览器,通过web端,来获取和修改资源。
通过web控制的demo
我们基于上文简单的demo进行一下改造,不过在此之前要下载一个jar包,因为通过web控制所需的jar包并不在jdk自带的jar中,连接http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html, 选那个jmx-1_2_1-ri.zip就好,解压后把jmxtools那个jar加到classpath就可以了。接下来,写代码。MBean不用改,在代理层的代码下面加上以下几行代码:
// create a html adapter so as to control jmx by web page ObjectName htmlAdapterName = new ObjectName("hello:name=htmlAdapter,port=8082"); // create a html adapter server, register and start HtmlAdaptorServer adaptorServer = new HtmlAdaptorServer(); server.registerMBean(adaptorServer, htmlAdapterName); adaptorServer.start();
将MBean注册到server之后,我们要在本地启动一个服务器以供来自web的连接。这个HtmlAdapterServer就是架构图中,供web端访问的适配器,同样需要把它注册到代理层的server中,然后调用start()方法,供web端访问的服务就开启了。
你只需要打开浏览器,输入localhost:8082,你就能看到当前你的jvm中注册的资源。仔细找找,你会发现刚刚自己写的MBean也在其中,点击这个连接,在MBean的视图中,你能看到对应属性,是否可读写,当前值。同时自己可以修改该属性。有点意思哈~
这里有个问题,你会发现,当你将ObjectName中的port属性改为其他端口时,仍旧只能访问8082端口,其他端口无效。所以也就意味着这个HtmlAdapterServer的端口值不是在这里设置的。这个问题我们后文再讲。
通过客户端控制的demo
上文中通过web控制的demo,可以作为查询、调控的界面,通过人工去控制。可是有些情况下,需要通过程序自动触发,比如你需要每隔十分钟更改一下资源值,这个时候通过人工控制就不现实了。接下来我们写一个通过客户端控制的demo。
同样,我们的MBean不用改,仍是要改代理层的server,基于上文那个简单的demo,在将资源MBean注册到server后,添加如下几行代码
// register a port LocateRegistry.createRegistry(9999); // initial a url and get a jmx connector server instance JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi"); JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server); System.out.println("before connector server start...."); connectorServer.start(); System.out.println("connector server has started......");
这里我们创建了一个JMXConnectorServer,其实架构图中也已经画出了,是通过客户端访问的连接器。
本地注册一个端口,然后创建一个url传给这个connector,调用start()方法,这样就在本地启动了一个以供客户端连接的服务器。
我们发现这个url的格式有点奇怪,其实这也是Jmx规定的,比如以`service:jmx` 作为开头,默认实现rmi方式等,这个后文再讲。
<
4000
p>服务器启动起来了,我们再建立一个自己的客户端。可以新建一个程序,几行代码,如下:
// new jmx url JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi"); // connect JMXConnector connector = JMXConnectorFactory.connect(url); // get a connection instance MBeanServerConnection connection = connector.getMBeanServerConnection(); //objectName must be same as which was register on server ObjectName objectName = new ObjectName("hello:name=HelloWorld"); // get attribute before change String helloWorld = (String) connection.getAttribute(objectName, "HelloWorld"); System.out.println("before" + helloWorld); // set attribute connection.setAttribute(objectName, new Attribute("HelloWorld", "client")); helloWorld = (String) connection.getAttribute(objectName, "HelloWorld"); System.out.println("after : " + helloWorld);
结合注释,很容易看懂。通过相同的url,连接到已经创建好的服务器,之后的查询和修改资源的过程跟之前一样,不再多说。
本章先简单介绍几个简单的demo,也遗留下来很多问题,接下来的文章继续解答。
相关文章推荐
- (JMX读书笔记)-JMX核心:资源管理
- 基于Spring+JMX+Tomcat实现资源动态管理
- Tomcat+red5+ffmpeg实现流媒体资源管理和在线直播
- [资源]学生信息管理系统+access源代码 附上实训报告
- Effective C++(三)资源管理
- PHP编程的文件资源管理一例
- RH436之高级资源管理
- 《Effective C ++ 》资源管理:条款25--考虑写出一个不抛出异常的swap函数
- 5.资源管理
- Flex RSL作资源共享管理
- 《Effective C++》资源管理:条款26-条款27
- 用maven管理的javaWeb项目无法找到.properties等资源文件
- 信息资源管理——基础
- 资源推荐 五个常用MySQL图形化管理工具
- Android中资源管理机制详细分析
- SpringMVC拦截器(资源和权限管理)
- 管理Web应用静态资源一招鲜
- Finalization [3] 外部资源对象生命期管理和句柄重用攻击
- Android资源管理框架(Asset Manager)简要介绍
- SpringMVC拦截器(资源和权限管理)