首先让别的程序连接到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的思想和技巧,希望大家能给点意见。
分享到:
相关推荐
首先,`cmdline-jmxclient-0.10.3.jar`是一个命令行Java Management Extensions (JMX)客户端,它允许通过JMX协议远程访问和管理Java应用程序,如Tomcat。JMX是一种标准的Java技术,用于管理和监控Java应用程序的运行...
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. ...
8. **Spring Boot与ActiveMQ**:在Spring Boot应用中,可以利用 starters 来简化配置,通过`spring.activemq.broker-url`和`spring.activemq.user`等属性快速设置ActiveMQ连接。 9. **消息确认**:ActiveMQ支持两种...
com.kingdee.bos.appframework.client.servicebinding com.kingdee.bos.appframework.databinding com.kingdee.bos.appframework.exception com.kingdee.bos.appframework.stateManage ...
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 应用程序的强大工具。它提供了一个用户友好的界面,允许开发者实时查看应用程序的状态、日志、JVM指标等信息,从而帮助进行故障排查和性能优化。 首先...
- **JCA CCI:** Spring 支持 JCA(Java Connector Architecture)和 CCI(Common Client Interface),用于连接外部系统。 - **EMAIL:** Spring 提供了邮件发送支持。 - **Task Execution and Scheduling:** ...
2. **配置Spring**:创建一个Spring配置文件(如`cxf-servlet.xml`),在这个文件中定义CXF的服务发布和消费者配置。你可以使用Spring的`jaxws:endpoint`或`jaxrs:server`标签来声明服务端点,`jaxws:client`或`jax...
这会在Spring容器中创建一个名为`memcachedClient`的bean,连接到指定的memcached服务器。 **复杂例子** ```xml <bean name="memcachedClient" class="net.rubyeye.xmemcached.utils.XMemcachedClientFactoryBean">...
SpringBoot Admin是一款基于Spring Boot的管理系统,用于实时监控Spring Boot应用的状态和性能。这个压缩包“springboot-admin-master.zip”很可能包含了一个完整的SpringBoot Admin项目源码,供开发者学习和使用。...
创建一个新的Spring Boot项目,并添加SpringAdmin Server和SpringAdmin Client的依赖。对于Maven用户,可以在`pom.xml`文件中添加以下依赖: ```xml <groupId>de.codecentric <artifactId>spring-boot-admin-...
同时,需要将`catalina-jmx-remote.jar`和`cmdline-jmxclient.jar`放在Tomcat的`lib`目录下,以支持远程JMX连接。 3. **配置Zabbix代理**: 在Zabbix服务器上,我们需要安装Zabbix代理或者配置Zabbix Server直接监控...
Spring Boot Admin 是一个用于监控 Spring Boot 应用程序的工具,它提供了一个用户友好的界面来展示应用的状态、日志、JMX 操作以及健康检查等信息。在这个名为 "spring-boot-admin-samples" 的项目中,我们将深入...
String value = (String) client.get("testKey"); System.out.println(value); // 清理资源 IOUtils.closeQuietly((Session) client); } catch (Exception e) { e.printStackTrace(); } } } ``` #### 总结...
要消费Hession服务,同样在Spring配置文件中,使用`<hessian:client>`标签指定服务地址和接口,Spring会创建一个代理对象,使得开发者可以直接调用远程服务,就像调用本地方法一样。 5. **安全性考虑** 虽然...
在这里,我们将详细介绍 Spring Boot Admin 的使用详解,包括配置 Server 端和 Client 端、显示应用版本、JMX-bean 管理等。 一、前言 Spring Boot Admin 用于监控基于 Spring Boot 的应用程序。官方文档提供了...
在实际应用中,确保正确配置和管理连接池至关重要,因为连接池能够提升并发处理能力,但需要保证数据之间的独立性,或者使用CAS(Check-And-Set)操作来保证操作的原子性。同时,监控JMX指标可以帮助了解系统运行状况...
【XMemcached用户指南】 XMemcached是一款专为Java开发者设计的高效、强大的Memcached客户端。Memcached是一种高性能的分布式内存对象...通过深入理解和正确使用XMemcached,可以有效地提升应用程序的性能和可扩展性。
3. 监控与日志:Java应用在K8s中运行时,可以通过JMX、Prometheus和Jaeger等工具进行性能监控和追踪。同时,结合Logback或Log4j等日志框架,将日志发送到K8s的日志管理系统(如Elasticsearch、Fluentd)。 二、...
memcachedClient.set("hello", 0, "Hello, xmemcached"); // 获取数据 String value = memcachedClient.get("hello"); System.out.println(value); } finally { memcachedClient.shutdown(); } ``` 这段代码...