`
baallee
  • 浏览: 11878 次
  • 性别: Icon_minigender_1
  • 来自: zh
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Spring 2.x jmx 及应用(3)client连接和通知

阅读更多

首先让别的程序连接到mbeanServer必须有个serverConnectior
只需在mbeanServer的配置文件中定义一个
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean"/>	

即可完成对连接的监听
这样设定是使用默认的及jmxmp协议service:jmx:jmxmp://localhost:9875
你也可以通过使用其他jmx支持的协议RMI,IIOP, Burlap,Hessian,SOAP等,
只要设定objectName和serviceUrl及可
为了方便我们常用的还是jmxmp.

server配置好到client了。
client同样需要一个连接器
<bean id="clientConnector"
	class="org.springframework.jmx.support.MBeanServerConnectionFactoryBean">
	<property name="serviceUrl"
		value="service:jmx:jmxmp://localhost:9875" />
</bean>

简单直观的配置没什么可以说的。

操作mbean.
无论你使用那种方式注册和描述mbean,访问和操作mbean的方式只有一种。就是通过interface创建的代理来访问。
<bean id="proxy"
		class="org.springframework.jmx.access.MBeanProxyFactoryBean">
		<property name="objectName" value="mbean:name=testBean" />
		<property name="proxyInterface"
			value="com.xmlasia.spring.test.jmx.ICommentMBeanManager" />
		<property name="server" ref="clientConnector" />
	</bean>

同样简单直观,这里注意proxyInterface不是数组类型。你只能设定一个interface,无论server是不是用interface暴露的,只要client的interface于mbeanServer中的匹配就能正确访问


如果你不是使用interface暴露的mbean的方法,当你调用不匹配的method时会有
org.springframework.jmx.access.InvalidInvocationException: Operation 'publicMessage' is not exposed on the management interface从客户段抛出。所以在实际应用时最

好能使用interface配置mbean.

测试
public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("/jmxClientContext.xml");
		ICommentMBeanManager o = (ICommentMBeanManager)context.getBean("proxy");
		o.pause("testid");
		o.shutDown();

		while(true){
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}


同样client的连接是不阻塞主线程的,同样需要保持主线程的活着。
调用上述代码就能看到server有调用mbean的方法。

通知
jmx有一种机制和向容器通知属性改变,首先我们需要了解NotificationListener
package com.xmlasia.spring.test.jmx;

import javax.management.Notification;
import javax.management.NotificationListener;

public class TestNotificationListener implements NotificationListener {

	@Override
	public void handleNotification(Notification notification, Object obj) {
		System.out.println(notification);
	}

}

实现一个NotificationListener,可以看到NotificationListener是标准的jmx接口
当属性值改变时handleNotification将会调用。

使用MBeanExporter的notificationListenerMappings属性将listener和mbean进行mapping
<bean id="mBeanExporter"
		class="org.springframework.jmx.export.MBeanExporter">
		<property name="server" ref="mbeanServer" />
		<property name="assembler" ref="assembler" />
		<property name="beans">
			<!-- 将mbean注册到mBeanExporter -->
			<map>
				<entry key="mbean:name=testBean"
					value-ref="mbeanManager" />
			</map>
		</property>
		<property name="registrationBehaviorName"
			value="REGISTRATION_REPLACE_EXISTING" />		
		<property name="notificationListenerMappings">
			<map>
				<!--将所有listener mapping到所有mbean-->
				<entry key="*">
					<bean class="com.xmlasia.spring.test.jmx.TestNotificationListener" />
				</entry>
			</map>
		</property>
	</bean>

key是同配符,也可以指定到某一个mbean

当我们在client调用.setClientStatus是handleNotification收到的
notification = javax.management.AttributeChangeNotification[source=mbean:name=testBean][type=jmx.attribute.change][message=AttributeChangeDetected]
一般情况下这样的通知没有意义,我们要将他filter掉。
package com.xmlasia.spring.test.jmx;

import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;

public class TestNotificationListener implements NotificationListener,
		NotificationFilter {

	@Override
	public void handleNotification(Notification notification, Object obj) {
		System.out.println(notification);
	}

	@Override
	public boolean isNotificationEnabled(Notification notification) {
		if (notification instanceof javax.management.AttributeChangeNotification)
			return false;
		else
			return true;
	}
}

同样实现标准的jmx接口NotificationFilter
我们通过判断他的类型进行过滤。
改变配置文件。不使用notificationListenerMappings属性,改用notificationListeners
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

	<bean id="mbeanManager"
		class="com.xmlasia.spring.test.jmx.MBeanManager" />

	<bean id="mbeanServer"
		class="org.springframework.jmx.support.MBeanServerFactoryBean">
	</bean>

	<bean id="assembler"
		class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
		<property name="attributeSource" ref="jmxAttributeSource" />
	</bean>
	
	<bean id="jmxAttributeSource"
		class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
	
	<bean id="mBeanExporter"
		class="org.springframework.jmx.export.MBeanExporter">
		<property name="server" ref="mbeanServer" />
		<property name="assembler" ref="assembler" />
		<property name="beans">
			<map>
				<entry key="mbean:name=testBean"
					value-ref="mbeanManager" />
			</map>
		</property>
		<property name="notificationListeners">
			<list>
				<bean
					class="org.springframework.jmx.export.NotificationListenerBean">
					<constructor-arg ref="testNotificationListener" />
					<property name="mappedObjectNames">		
						<list>	
							<value>mbean:name=testBean</value>
						</list>							
					</property>
					<property name="notificationFilter"
						ref="testNotificationListener" />
				</bean>
			</list>
		</property>
	</bean>
	
	<bean id="testNotificationListener" class="com.xmlasia.spring.test.jmx.TestNotificationListener"/> 
	
	<bean id="serverConnector"
		class="org.springframework.jmx.support.ConnectorServerFactoryBean" />
</beans>

完整的配置
我们注入一个spring为我们封装好的NotificationListenerBean,可以将listener,filter,还有objectname方便组织在一起。
这里要特别说明下mappedObjectNames是String[]类的,spring reference中的例子是错误的。

下面我们要自己发布notification
package com.xmlasia.spring.test.jmx;   
  
import javax.management.Notification;

import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedOperationParameter;
import org.springframework.jmx.export.annotation.ManagedOperationParameters;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.export.notification.NotificationPublisher;
import org.springframework.jmx.export.notification.NotificationPublisherAware;
  
@ManagedResource  
public class MBeanManager implements NotificationPublisherAware {   
    private int clientStatus;   
  
    private NotificationPublisher publisher;

    
    @ManagedOperation(description = "pause a single proccess")   
    @ManagedOperationParameters( { @ManagedOperationParameter(name = "Name of proccess instance", description = "Mandatory") })   
    public void pause(String n) {   
        System.out.println("pause proccess id :" + n);   
    }   
  
    @ManagedOperation(description = "shut down the proccess")   
    public void shutDown() {   
        System.out.println("shutting down...");   
    }   
  
    public void publicMessage() {   
        System.out.println("public Message to monitor server");   
    }   
  
    @ManagedAttribute(description = "client status")   
    public int getClientStatus() {   
        return clientStatus;   
    }   
  
    @ManagedAttribute(description = "client status")   
    public void setClientStatus(int clientStatus) {   
        this.clientStatus = clientStatus;  
        publisher.sendNotification(new Notification("set",this,0,"client Status changed"));
    }

	@Override
	public void setNotificationPublisher(
			NotificationPublisher notificationPublisher) {
		publisher = notificationPublisher;
	}   
}   

我们只需要implements NotificationPublisherAware 的setNotificationPublisher方法就可以方便的使用
自己的publisher,提供有用的信息到listener中。
Spring会在exporter创建mbean时帮我们传入NotificationPublisher。

Spring对jmx的封装已经看完了。从中可以学到很多Spring的思想和技巧,希望大家能给点意见。



分享到:
评论
2 楼 baallee 2007-07-26  
jconsole可以连的,他会自动帮你搜索jvm的pid连过去。
用rmi就需要用到jndi,jnid需要有jndi的容器。比较麻烦。
不如用jmxmp简单直接。把自己application当做server,我个人比较喜好用这个协议
1 楼 popi 2007-07-25  
谢谢你的这三篇文章。
以前没有搞过jmx,只是顺着你的文章,结合sping doc把你提到的例子走了一遍。有个问题:
为什么我用jconsole连不上server呢?用client可以的。
还有一个弱问题:按照你的文章来看,这些例子用rmi完全可以实现,为什么要定义一种新的协议来实现这样的功能的?

相关推荐

    cmdline-jmxclient-0.10.3.jar + zabbix tomcat监控模板

    首先,`cmdline-jmxclient-0.10.3.jar`是一个命令行Java Management Extensions (JMX)客户端,它允许通过JMX协议远程访问和管理Java应用程序,如Tomcat。JMX是一种标准的Java技术,用于管理和监控Java应用程序的运行...

    spring-boot-reference.pdf

    20.5.2. Remote Update 21. Packaging Your Application for Production 22. What to Read Next IV. Spring Boot features 23. SpringApplication 23.1. Startup Failure 23.2. Customizing the Banner 23.3. ...

    SpringActiveMQ.rar

    8. **Spring Boot与ActiveMQ**:在Spring Boot应用中,可以利用 starters 来简化配置,通过`spring.activemq.broker-url`和`spring.activemq.user`等属性快速设置ActiveMQ连接。 9. **消息确认**:ActiveMQ支持两种...

    金蝶BOSV6.1_业务组件API参考手册

    com.kingdee.bos.appframework.client.servicebinding com.kingdee.bos.appframework.databinding com.kingdee.bos.appframework.exception com.kingdee.bos.appframework.stateManage ...

    《activmq in action 》

    2. Understanding Message-Oriented Middleware and JMS ................... 21 2.1. Introduction to Enterprise Messaging ....................................... 22 2.2. What is Message Oriented ...

    spring boot admin server

    Spring Boot Admin Server 是一个用于监控和管理 Spring Boot 应用程序的强大工具。它提供了一个用户友好的界面,允许开发者实时查看应用程序的状态、日志、JVM指标等信息,从而帮助进行故障排查和性能优化。 首先...

    spring_FrameWork3.0

    - **JCA CCI:** Spring 支持 JCA(Java Connector Architecture)和 CCI(Common Client Interface),用于连接外部系统。 - **EMAIL:** Spring 提供了邮件发送支持。 - **Task Execution and Scheduling:** ...

    WebService的CXF整合Spring

    2. **配置Spring**:创建一个Spring配置文件(如`cxf-servlet.xml`),在这个文件中定义CXF的服务发布和消费者配置。你可以使用Spring的`jaxws:endpoint`或`jaxrs:server`标签来声明服务端点,`jaxws:client`或`jax...

    xmemcache与SPRING整合

    这会在Spring容器中创建一个名为`memcachedClient`的bean,连接到指定的memcached服务器。 **复杂例子** ```xml &lt;bean name="memcachedClient" class="net.rubyeye.xmemcached.utils.XMemcachedClientFactoryBean"&gt;...

    springboot-admin-master.zip

    SpringBoot Admin是一款基于Spring Boot的管理系统,用于实时监控Spring Boot应用的状态和性能。这个压缩包“springboot-admin-master.zip”很可能包含了一个完整的SpringBoot Admin项目源码,供开发者学习和使用。...

    springadmin项目

    创建一个新的Spring Boot项目,并添加SpringAdmin Server和SpringAdmin Client的依赖。对于Maven用户,可以在`pom.xml`文件中添加以下依赖: ```xml &lt;groupId&gt;de.codecentric &lt;artifactId&gt;spring-boot-admin-...

    zabbix监控tomcat

    同时,需要将`catalina-jmx-remote.jar`和`cmdline-jmxclient.jar`放在Tomcat的`lib`目录下,以支持远程JMX连接。 3. **配置Zabbix代理**: 在Zabbix服务器上,我们需要安装Zabbix代理或者配置Zabbix Server直接监控...

    spring-boot-admin-samples

    Spring Boot Admin 是一个用于监控 Spring Boot 应用程序的工具,它提供了一个用户友好的界面来展示应用的状态、日志、JMX 操作以及健康检查等信息。在这个名为 "spring-boot-admin-samples" 的项目中,我们将深入...

    xmemcached 中文开发手册

    String value = (String) client.get("testKey"); System.out.println(value); // 清理资源 IOUtils.closeQuietly((Session) client); } catch (Exception e) { e.printStackTrace(); } } } ``` #### 总结...

    hession文档(与spring兼容)

    要消费Hession服务,同样在Spring配置文件中,使用`&lt;hessian:client&gt;`标签指定服务地址和接口,Spring会创建一个代理对象,使得开发者可以直接调用远程服务,就像调用本地方法一样。 5. **安全性考虑** 虽然...

    Spring Boot Admin 的使用详解

    在这里,我们将详细介绍 Spring Boot Admin 的使用详解,包括配置 Server 端和 Client 端、显示应用版本、JMX-bean 管理等。 一、前言 Spring Boot Admin 用于监控基于 Spring Boot 的应用程序。官方文档提供了...

    Xmemcached用户指南.pdf

    在实际应用中,确保正确配置和管理连接池至关重要,因为连接池能够提升并发处理能力,但需要保证数据之间的独立性,或者使用CAS(Check-And-Set)操作来保证操作的原子性。同时,监控JMX指标可以帮助了解系统运行状况...

    Xmemcached用户指南.docx

    【XMemcached用户指南】 XMemcached是一款专为Java开发者设计的高效、强大的Memcached客户端。Memcached是一种高性能的分布式内存对象...通过深入理解和正确使用XMemcached,可以有效地提升应用程序的性能和可扩展性。

    k8s-test_java和k8s_k8s环境日常_k8s_

    3. 监控与日志:Java应用在K8s中运行时,可以通过JMX、Prometheus和Jaeger等工具进行性能监控和追踪。同时,结合Logback或Log4j等日志框架,将日志发送到K8s的日志管理系统(如Elasticsearch、Fluentd)。 二、...

    Xmemcached用户指南

    memcachedClient.set("hello", 0, "Hello, xmemcached"); // 获取数据 String value = memcachedClient.get("hello"); System.out.println(value); } finally { memcachedClient.shutdown(); } ``` 这段代码...

Global site tag (gtag.js) - Google Analytics