- 浏览: 151787 次
- 性别:
- 来自: 北京
最新评论
-
pandengzhegt:
好牛!正需要!谢谢了!
JPA 2.0 中的动态类型安全查询 -
yanlp:
万分的感谢。
仿google 的输入提示框 -
huangwenji6111:
可谓良师,在此拜谢!受益匪浅!
hibernate lazy -
jwx0925:
不错!mark!
hibernate对象状态 -
leftstick:
大有裨益,谢了!
hibernate lazy
RMI(Remote Method Invocation)
RMI是不同JVM之间的对象通信的协议
JMX RMI访问的基本步骤:
1
启动MBeanServer
2
建立并启动 NamingService MBean,实际就是rmiregistry
3
为MBeanServer建立160 JMX RMIConnector,此RMI连接器提供:
service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxconnector
4
客户端连接
4.1
通用客户端(如jconsole)
4.2
自定义客户端
生成 JMXConnector ,与JMI server建立 RMI连接
建立与MBean server的连接
MBeanServerInvocationHandler.newProxyInstance()获取代理MBean
JMX RMI例子
1. RMI Server
package com.machome.jmx.appTest;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import com.machome.bean.Hello;
import mx4j.tools.naming.NamingService;
public class RmiServer
{
private MBeanServer mBeanServer;
private JMXConnectorServer connectorServer;
private JMXServiceURL jmxUrl;
public RmiServer() throws Exception{
mBeanServer = MBeanServerFactory.createMBeanServer();
createRmiregistry();
CreateJMXConnector();
}
public static void main(String[] args) throws Exception
{
RmiServer rmiServer = new RmiServer();
// 加一个测试MBean Hello对象
rmiServer.addMbean(new Hello(), "mbean", "name", "hello");
rmiServer.startJMXConnector();
System.out.println("Server up and running");
}
public ObjectName addMbean(Object o,String domain,String key,String value) throws Exception{
ObjectName oName = new ObjectName(domain, key, value);
mBeanServer.registerMBean(o, oName);
return oName;
}
public void createRmiregistry() throws Exception{
// 1.注册NamingService MBean
ObjectName namingName = ObjectName
.getInstance("naming:type=rmiregistry");
// 这里采用MC4J的mx4j.tools.naming.NamingService
NamingService ns = new NamingService();
mBeanServer.registerMBean(ns, namingName);
// 2.启动NamingService MBean
mBeanServer.invoke(namingName, "start", null, null);
}
public void CreateJMXConnector() throws Exception{
// 1.nammingPort,从NamingService获得Port,缺省是1099
ObjectName namingName = ObjectName.getInstance("naming:type=rmiregistry");
int namingPort = ((Integer)mBeanServer.getAttribute(namingName, "Port")).intValue();
// 2. jndiPath
String jndiPath = "/jmxconnector";
// 3. JMXServiceURL ,为:
// service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxconnector
jmxUrl = new JMXServiceURL("service:jmx:rmi://localhost/jndi/rmi://localhost:"
+ namingPort + jndiPath);
// 4.Create and start the RMIConnectorServer
// 中间设为null的参数,是针对认证的,我们这里没打开,设为null
connectorServer = JMXConnectorServerFactory
.newJMXConnectorServer(jmxUrl, null, mBeanServer);
}
public void startJMXConnector() throws Exception{
connectorServer.start();
}
public void stopJMXConnector() throws Exception{
connectorServer.stop();
}
}
执行此RmiServer:
Server up and running
可以看到TCP 1099端口被listen
D:\Documents and Settings\mac>netstat -an
Active Connections
Proto Local Address Foreign Address State
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING
TCP 0.0.0.0:1025 0.0.0.0:0 LISTENING
TCP 0.0.0.0:1099 0.0.0.0:0 LISTENING
TCP 0.0.0.0:2737 0.0.0.0:0 LISTENING
TCP 0.0.0.0:3306 0.0.0.0:0 LISTENING
TCP 0.0.0.0:6059 0.0.0.0:0 LISTENING
TCP 0.0.0.0:6648 0.0.0.0:0 LISTENING
2.通用客户端(典型的比如jconsole)
这里用的是jdk 1.6 jconsole
远程进程:
service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxconnector
用户名:
口令:
用户名和口令都可以空着,不必输入
点"连接",可以进入jconsole界面
可以在mbean下看到hello对象
3. 自定义client 端通过RMI连接 Server
package com.machome.jmx.appTest;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.MBeanServerDelegateMBean;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import com.machome.bean.Hello;
import com.machome.bean.HelloMBean;
public class RmiClient
{
private JMXServiceURL jmxUrl;
private JMXConnector connector;
private MBeanServerConnection mBeanServerconnection;
public RmiClient()throws Exception{
createJMXRmiConnector();
createMBeanServerConnection();
}
public static void main(String[] args) throws Exception
{
new RmiClient().test();
}
private void createJMXRmiConnector() throws Exception{
// 1.The JMXConnectorServer protocol
String serverProtocol = "rmi";
// 2.The RMI server's host
// this is actually ignored by JSR 160
String serverHost = "localhost";
// 3.The host, port and path where the rmiregistry runs.
String namingHost = "localhost";
int namingPort = 1099;
String jndiPath = "/jmxconnector";
// 4. connector server url
jmxUrl = new JMXServiceURL("service:jmx:" +
serverProtocol + "://" + serverHost +
"/jndi/rmi://" + namingHost + ":" +
namingPort + jndiPath);
// 5. 生成 JMXConnector,连接到url一端
// Connect a JSR 160 JMXConnector to the server side
connector = JMXConnectorFactory.connect(jmxUrl);
}
private void createMBeanServerConnection() throws Exception{
mBeanServerconnection = connector.getMBeanServerConnection();
}
public void test()throws Exception{
ObjectName oName = new ObjectName("mbean", "name", "hello");
// 获取代理对象
Object proxy = MBeanServerInvocationHandler
.newProxyInstance(mBeanServerconnection,oName, HelloMBean.class, true);
// 获取测试MBean,并执行它的(暴露出来被管理监控的)方法
HelloMBean helloMBean = (HelloMBean)proxy;
helloMBean.setName("mac");
helloMBean.printHello();
helloMBean.printHello("haha");
}
}
执行:
Server up and running
Hello, mac
Hello, haha
上面例子中RMI中的rmiregistry MBean,我们采用的mc4j-tools.jar中的 NamingService,代码如下,代码并不复杂,其实我们也可以自定义一个代替它:
public class NamingService implements NamingServiceMBean
{
public NamingService()
{
this(1099);
}
public NamingService(int port)
{
setPort(port);
}
public void setPort(int port)
{
if(isRunning())
{
throw new IllegalStateException("NamingService is running, cannot change the port");
} else
{
m_port = port;
return;
}
}
public int getPort()
{
return m_port;
}
public boolean isRunning()
{
return m_running;
}
public void start()
throws RemoteException
{
if(!isRunning())
{
m_registry = LocateRegistry.createRegistry(getPort());
m_running = true;
}
}
public void stop()
throws NoSuchObjectException
{
if(isRunning())
m_running = !UnicastRemoteObject.unexportObject(m_registry, true);
}
public String[] list()
throws RemoteException
{
if(!isRunning())
throw new IllegalStateException("NamingService is not running");
else
return m_registry.list();
}
public void unbind(String name)
throws RemoteException, NotBoundException
{
if(!isRunning())
{
throw new IllegalStateException("NamingService is not running");
} else
{
m_registry.unbind(name);
return;
}
}
private int m_port;
private Registry m_registry;
private boolean m_running;
}
MBean接口:
public interface NamingServiceMBean
{
public abstract void setPort(int i);
public abstract int getPort();
public abstract boolean isRunning();
public abstract void start()
throws RemoteException;
public abstract void stop()
throws NoSuchObjectException;
public abstract String[] list()
throws RemoteException;
public abstract void unbind(String s)
throws RemoteException, NotBoundException;
}
spring 下的 RMI connector
1.spring 配置如下:
<!-- 1.定义自己的bean -->
<bean id="hello" class="com.machome.bean.Hello" />
<!-- JMX configuration -->
<!-- 2.创建一个mbeanServer bean-->
<!-- 如果你的spring是应用在容器中,则不需要此步骤,此步骤用于单独建立独立的MBeanServer中
<bean id="mbeanServer"
class="org.springframework.jmx.support.MBeanServerFactoryBean">
</bean>
-->
<!-- 3.定义assembler bean ,装配bean
MetadataMBeanInfoAssembler是AutodetectCapableMBeanInfoAssembler 唯一实现
spring文档中有专门介绍AutodetectCapableMBeanInfoAssembler的章节
-->
<bean id="assembler"
class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<!-- 注入下面定义的jmxAttributeSource-->
<property name="attributeSource" ref="jmxAttributeSource"/>
</bean>
<!-- 4.定义解释mbean中Annotation的bean-->
<bean id="jmxAttributeSource"
class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
<!-- 5.定义 RMI连接器,注意需要先定义一个naming 注册 bean-->
<bean id="registry"
class="org.springframework.remoting.rmi.RmiRegistryFactoryBean"
destroy-method="destroy">
<property name="port" value="1099" />
</bean>
<bean id="serverConnector"
class="org.springframework.jmx.support.ConnectorServerFactoryBean"
depends-on="registry">
<property name="objectName" value="connector:name=rmi"/>
<property name="serviceUrl"
value="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxconnector"/>
<!-- 如果上面步骤2.你单独定义一个mbeanServer,这里需要指定,否则rmi connector缺省是去寻找runtime环境内的MBeanserver(通常是容器的MBeanServer)
<property name="server" ref="mbeanServer"/>
-->
<!-- 多线程启动connector,一个线程一个connector -->
<property name="threaded" value="true" />
<!-- 多线程启动connector,thread daemon -->
<property name="daemon" value="true" />
</bean>
<!-- 6.定义MBeanExporter bean, 这是spring jmx最核心的类 -->
<bean id="mBeanExporter" class="org.springframework.jmx.export.MBeanExporter"
lazy-init="false">
<!-- 注入上面定义的assembler 两个bean注入-->
<property name="assembler" ref="assembler"/>
<!-- 如果上面步骤2.你单独定义一个mbeanServer,这里需要指定,否则export bean缺省是去寻找runtime环境内的MBeanserver(通常是容器的MBeanServer)
<property name="server" ref="mbeanServer"/>
-->
<!-- 将1.里面定义的mbean注册到mBeanExporter bean中 -->
<property name="beans">
<map>
<entry key="mbean:name=hello" value-ref="hello"/>
</map>
</property>
</bean>
2. web.xml装载spring 配置
<!-- ##################### 初始化spring容器 ###########-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:ssh-mysql.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
3.将项目部署入Tomcat
启动Tomcat
不需要执行任何servlet,action,只要spring随Tomcat启动,就会看到TCP 1099端口被listen
D:\Documents and Settings\mac>netstat -an
Active Connections
Proto Local Address Foreign Address State
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING
TCP 0.0.0.0:1025 0.0.0.0:0 LISTENING
TCP 0.0.0.0:1099 0.0.0.0:0 LISTENING
TCP 0.0.0.0:2737 0.0.0.0:0 LISTENING
4. 执行通用客户端(典型的比如jconsole)
这里用的是jdk 1.6 jconsole
远程进程:
service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxconnector
用户名:
口令:
用户名和口令都可以空着,不必输入
点"连接",可以进入jconsole界面
与前面application RMI的例子不同,这里的不仅可以看到hello MBean对象,还能看到很多MBean对象,如Catalina目录下的很多MBean,因为spring没有定义新的MBeanServer,而是用 tomcat容器自己的MBeanServer,所以能看到很多Tomcat容器自己的service MBean
5.执行前面application RMI的例子的RmiClient
Hello, mac
Hello, haha
(我在spring rmi 例子和application rmi 例子用的相同的serviceUrl,都是
service:jmx:rmi://localhost/jndi/rmi: //localhost:1099/jmxconnector
因此客户端可以访问这两种例子的Server)
简化后的spring RMI
其实spring 例子里的spring 配置的no.2,no.3.no.4都可以不用
MBeanServer可以不用建立,spring会自动搜索容器自己的MBeanServer,
MBeanInfoAssembler和AnnotationJmxAttributeSource 则只是提供注释MBean功能,以代替implement MBean接口,完全可以不用这种注释,而用传统的implement MBean接口
<!-- 1.定义自己的bean -->
<bean id="hello" class="com.machome.bean.Hello" />
<!-- 5.定义 RMI连接器,注意需要先定义一个naming 注册 bean-->
<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean" destroy-method="destroy">
<property name="port" value="1099" />
</bean>
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean" depends-on="registry">
<property name="objectName" value="connector:name=rmi"/>
<property name="serviceUrl" value="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxconnector"/>
<!-- 多线程启动connector,一个线程一个connector -->
<property name="threaded" value="true" />
<!-- 多线程启动connector,thread daemon -->
<property name="daemon" value="true" />
</bean>
<!-- 6.定义MBeanExporter bean, 这是spring jmx最核心的类 -->
<bean id="mBeanExporter" class="org.springframework.jmx.export.MBeanExporter"
lazy-init="false">
<!-- 将1.里面定义的mbean注册到mBeanExporter bean中 -->
<property name="beans">
<map>
<entry key="mbean:name=hello" value-ref="hello"/>
</map>
</property>
</bean>
发表评论
-
java实现Tree
2012-07-10 09:59 882/****************************** ... -
Java正则表达式应用总结
2012-05-25 12:23 1103一、概述 正则表达式是Java处理字符串、文本的重要工具。 ... -
JdbcTemplate与事务
2012-05-17 17:42 1127JdbcTemplate与事务 上例中的JdbcTemplat ... -
Java编程中“为了性能”尽量要做到的一些地方
2012-05-09 17:59 928最近的机器内存又爆满 ... -
jconsole远程监控Java进程
2012-05-07 11:44 1078JDK中的工具jconsole可以很好地监控Java进程及其运 ... -
spring集成quartz
2012-04-16 15:56 2223首先,让spring框架运转起来,可以参看一下:ht ... -
采用开发框架quartz调度管理Job
2011-07-11 10:03 19601.所需要的第三方包:quartz-1.5.2.jarcom ... -
java类型转换
2011-05-20 17:13 914string和int之间的转换? 字符串转换成数据 ... -
java整型数与网络字节序的 byte[] 数组转换关系
2011-05-05 10:47 3783因工作需要在java和c/c++之间进行socket通信,而 ... -
线程安全总结(二)
2010-11-12 10:34 853站内很多人都问我,所谓线程的“工作内存”到底是个什么东西? ... -
java线程安全总结
2010-11-12 10:33 837java线程安全总结(二 ... -
ora-02289问题解决
2010-10-19 12:35 1647<id name="id" type ... -
JDBC的批处理操作三种方式 pstmt.addBatch();
2010-09-25 15:58 8718SQL批处理是JDBC性能优化的重要武器,经本人研究总结,批处 ... -
log4j输出多个自定义日志文件
2010-05-12 10:28 1517<转>http://hi.baidu.com/ ... -
spring任务调度
2010-04-28 09:48 1410概述 在JDK 1.3以后的版本中,Java通过java.ut ... -
JDK线程池的使用
2010-04-07 16:35 1459一、简介 线程池类为 j ... -
Java文件操作
2010-02-06 15:29 874本文汇集常用文件操作方法,包括文件的建立/检查与删除,目录的建 ... -
[JMX一步步来] 6、Model Bean
2009-12-21 11:46 1213在上一节是用apache的commons-modeler来 ... -
[JMX一步步来] 5、用Apache的commons-modeler来辅助开发JMX
2009-12-21 11:45 1081一、前言 每一个MBean都要有一个接口,比如前面的Hello ... -
[JMX一步步来] 4、动态MBean:DynamicMBean
2009-12-21 11:37 1531一、前言 动态MBean是在运行期才定义它的属性和方法 ...
相关推荐
本文将深入探讨JMX的三种访问方式:HTTP页面方式、VM参数方式和RMI方式。 ### HTTP页面方式 1. **Servlet容器集成**:一种常见的实现JMX通过HTTP访问的方式是通过Servlet容器(如Tomcat)集成。开发者可以创建一个...
JMX以RMI方式连接的场景示例 JMX(Java Management Extensions)是一种Java技术,用于管理...JMX框架提供了一种灵活、可扩展和高效的方式来管理和监控应用程序,而RMI连接方式允许远程客户端访问MBean提供的管理功能。
MBeans可以是任何Java对象,它们暴露了管理接口,使得可以通过JMX API来访问和操作。 在本实例中,我们重点关注的是如何使用Remote Method Invocation(RMI)来实现JMX的MBean管理。RMI是一种在Java平台上进行远程...
在Java世界中,远程方法调用(Remote Method Invocation, RMI)和Java管理扩展(Java Management Extensions, JMX)是两个强大的工具,用于管理和监控分布式系统。本文将深入探讨如何利用RMI远程连接到Java虚拟机...
完成上述配置后,就可以使用之前获取的 JMX URL 来连接 TongWeb7 的 JMX 服务,例如 `service:jmx:rmi:///jndi/rmi://192.168.163.99:7200/jmxrmi`。你可以使用 Java 提供的 `jconsole` 工具,或者其他支持 JMX 的第...
3. `jmxri.jar`和`jmxtools.jar`:这两个JAR文件是JMX RMI实现的核心库,分别包含了RMI服务器和客户端的实现,使得远程JMX交互成为可能。 4. `jmxri.properties`和`jmxtools.properties`:这些配置文件可能包含了...
1. **配置JBoss**:在JBoss的配置文件(如`standalone.xml`或`domain.xml`)中启用JMX远程访问。这通常涉及开启JMX Remoting接口,并配置必要的安全设置。 2. **客户端设置**:在客户端,我们需要导入必要的JMX和...
3. 访问控制:通过对 JMX Agent 的访问控制,我们可以限制只有特定的用户或角色可以访问 JMX Agent。例如,我们可以使用 Role-Based Access Control(RBAC)来对 JMX Agent 进行访问控制。 通过采取这些措施,我们...
如果你的服务器不是运行在本地,你需要将`java.rmi.server.hostname`设置为服务器的公共IP地址或可解析的域名,以确保客户端可以从外部访问JMX服务。 ### 3. 客户端配置 客户端配置主要包括两部分:连接到JMX...
2. **设置RMI安全**:默认情况下,JMX远程访问是不安全的,需要在`$CATALINA_BASE/conf/server.xml`中配置RMIServerSocketFactory,以限制访问权限。可以使用SSL加密,或者在JMX连接器上设置特定的认证和授权策略。 ...
1. `jmxri.jar`: 这是JMX Remote Interface JAR文件,提供了JMX远程访问的支持。它实现了JSR 160(JMX Remote Protocol),允许远程管理应用程序或服务。`jmxri.jar`包含了远程连接、安全性以及传输协议相关的类。 ...
它们定义了客户端和服务器之间的通信协议,如JMX RMI连接器和JMX JMXMP连接器。连接器提供了安全机制,确保只有授权的客户端才能访问MBean服务器。 五、JMX工具和API 1. JMX API:包括MBean服务器接口、MBean接口...
JMX Remote Interface 是JMX框架的一部分,它允许远程访问和管理Java应用程序。jmxri.1.2.1.jar包含了实现JMX远程协议的类和接口,使得管理者能够通过网络来监控和控制运行在不同机器上的Java应用。这个库提供了RMI...
MBeans提供了暴露其状态和操作的方法,使得管理者可以通过JMX API进行访问和控制。例如,通过JMX,你可以动态地修改应用的配置参数,监控系统的性能指标,甚至触发特定的操作。 传统的配置方式通常需要修改源代码...
3. **启用远程访问**:配置JMX连接器,如RMI,允许远程客户端连接到MBeanServer。 4. **安全配置**:根据需求配置安全策略,控制谁可以访问哪些MBean。 5. **编写客户端代码**:在远程客户端,使用JMX连接器API建立...
4. **管理接口暴露**:可能通过JMX的RMI或者JMX Connectors暴露MBeanServer,使得远程客户端能够访问。 5. **客户端工具**:使用JConsole、VisualVM或其他支持JMX的工具,连接到MBeanServer,查看和操作MBean。 ...
它包含了服务器端的实现,比如MBeanServer,以及远程访问JMX代理的基础设施。 2. **jmxremote.jar**:这个库则主要涉及JMX的远程访问功能。它包含了支持JMX远程连接的类和配置,允许你从远程主机或不同的Java虚拟机...