【转】JMX实践-JMX连接端口
首先要从JMX URL说起。如下是一个典型的JMX URL:
service:jmx:rmi://localhost:5000/jndi/rmi://localhost:6000/jmxrmi
这个JMX URL可以分为如下几个部分:
service:jmx: 这个是JMX URL的标准前缀,所有的JMX URL都必须以该字符串开头。
rmi: 这个是connector server的传输协议,在这个url中是使用rmi来进行传输的。JSR 160规定了所有connector server都必须至少实现rmi传输,是否还支持其他的传输协议依赖于具体的实现。比如MX4J就支持soap、soap+ssl、hessian、burlap等等传输协议。
localhost:5000: 这个是connector server的IP和端口,该部分是一个可选项,可以被省略掉。(具体参见下文解释)
/jndi/rmi://localhost:6000/jmxrmi: 这个是connector server的路径,具体含义取决于前面的传输协议。比如该URL中这串字符串就代表着该connector server的stub是使用jndi api绑定在rmi://localhost:6000/jmxrmi这个地址。
如果在服务器端,我们用该URL创建一个connector server,则大概流程如下:
将connect server(javax.management.remote.rmi.RMIConnectorServer)内部的server对象(javax.management.remote.rmi.RMIJRMPServerImpl)的rmi stub export到本地的5000端口,接收外部连接
通过jndi api将该stub绑定在rmi://localhost:6000/jmxrmi这个地址上,这需要在本地的6000端口上运行着一个rmiregistry,如果不存在则会抛出异常
......
可以看到,如果在服务器端创建connector server时,该URL的第三部分(即localhost:5000)如果省略的话,则connector server会随机任意选择一个可用的端口。
如果在客户端,我们通过该URL创建一个connector,则大概按照如下的流程:
通过jndi api到rmi://localhost:6000/jmxrmi这个地址取回stub
stub中已经包含了真实服务器的地址,所以可以直接根据该stub连接到真实的服务器
......
可以看到,如果在客户端创建connector时,该URL的第三部分可以被省略掉。事实上我们也经常这么做,比如上面这个示例,在客户端建立connector所用的JMX URL可以被省略为:
service:jmx:rmi:///jndi/rmi://localhost:6000/jmxrmi
从这个示例中我们也可以看到,如果采用rmi作为传输协议的话,客户端需要进行两个连接。首先客户端连接到rmiregistry上得到真实服务器的stub(如rmi://localhost:6000/rmxrmi),然后客户端再根据该stub连接到真实的服务器上(如rmi://localhost:5000)。
在Sun Java 5.0的实现当中,可以通过指定运行期属性来配置JMX。比如:
-Dcom.sun.management.jmxremote.port=6000
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.password.file=conf/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=conf/jmxremote.access
除开密码和权限控制的配置外,这段运行期相当于一个如下的JMX URL:
service:jmx:rmi://localhost:0/jndi/rmi://localhost:6000/jmxrmi (红色部分可以被省略掉)
可以看到,通过指定com.sun.management.jmxremote.port属性,相当于指定了rmiregistry的运行端口,但是真正运行的服务器的stub export端口为0,会在运行期任意选择一个未被使用的端口号。如果该程序运行在防火墙后面,这个动态分配的端口号会让我们非常难以配置防火墙规则。
由于Sun Java 5.0实现的疏忽,并没有为我们提供一个运行期属性来配置stub export端口号,那么如何自定义一个JMX连接端口呢?
假设我们不传入任何运行期参数,仅通过代码来自定义一个connector server:
LocateRegistry.createRegistry(6000);
JMXConnectorServer cs = JMXConnectorServerFactory
.newJMXConnectorServer(url, env, beanServer);
cs.start();
第一行代码指明在6000端口创建一个rmiregistry。
第二行代码创建了一个connector server。第一个URL参数传入指定的JMXServiceURL,比如new JMXServiceURL("service:jmx:rmi://localhost:5000/jndi/rmi://localhost:6000/jmxrmi"),值得注意的是红色部分标出的IP和端口号要和第一步中创建的rmiregistry一致。第二个参数指定创建时的环境,我们可以暂时传入一个空Map。第三个参数指定要创建连接的MBeanServer,比如在Java 5.0下可以是ManagementFactory.getPlatformMBeanServer()。
第三行代码开启了创建的connector server。
这三行代码创建的connector server工作的很好,除了一点:真实的服务器没有任何认证和授权机制,会允许所有人访问。
自定义权限控制可以通过刚才第二行代码的第二个参数来进行设置:
Map env = new HashMap();
env.put(JMXConnectorServer.AUTHENTICATOR, JMXAuthenticator子类的实例);
比如在MX4J中就提供了一个mx4j.tools.remote.PasswordAuthenticator的类,通过配置文件来匹配用户名和密码;Sun也提供了一个com.sun.jmx.remote.security.JMXPluggableAuthenticator的类通过JAAS来配置验证和权限。用户可以参照这两个类来提供自定义的实现。这里提供一个简单的示例(不带任何效验机制,仅用于示例)
env.put(JMXConnectorServer.AUTHENTICATOR, new JMXAuthenticator() {
public Subject authenticate(Object credentials) {
String[] sCredentials = (String[]) credentials;
String userName = sCredentials[0];
String password = sCredentials[1];
if ("test".equals(userName) && "test".equals(password)) {
Set principals = new HashSet();
principals.add(new JMXPrincipal(user));
return new Subject(true, principals, Collections.EMPTY_SET,
Collections.EMPTY_SET);
}
throw new SecurityException("Authentication failed! "
+ message);
}
});
加入这段代码后,真实的服务器必须要验证后才能访问,但又有了一个新问题:rmiregistry没有任何验证。这意味着其他人可以把一个不相干的stub绑定到同一地址,从而替换掉真实服务器stub。好在幸运的是,无法把一个服务器端类路径上不存在的stub类绑定到rmiregistry,否则真实的用户名和密码就有可能被泄漏出去。
如果直接通过rmi对外提供的接口,我们没有办法修正这个问题,除非将代码绑定于特定的Java实现,比如Sun就直接通过它自己的rmi实现类来做(所以通过运行期参数配置jmx生成的rmiregistry是只读的,没有该安全性问题)。具体可参见sun.management.Agent和sun.management.jmxremote包下相关类。
但是我们可以换一个思路,比如不绑定到rmiregistry而绑定到其他的实现了验证机制的jndi provider,例如ldap上。由于bind jndi的代码在相关connector server的实现类中,比如javax.management.remote.rmi.RMIConnectorServer中bind jndi的代码:
void bind(String jndiUrl, Hashtable attributes,
RMIServer rmiServer, boolean rebind)
throws NamingException, MalformedURLException {
// if jndiURL is not null, we nust bind the stub to a
// directory.
InitialContext ctx =
new InitialContext(attributes);
if (rebind)
ctx.rebind(jndiUrl, rmiServer);
else
ctx.bind(jndiUrl, rmiServer);
ctx.close();
}
它在传入attributes时并没有特定的jndi的INITIAL_CONTEXT_FACTORY,所以我们可以通过两种方法来指定特定的INITIAL_CONTEXT_FACTORY:
在类路径上放上一个jndi.properties,配置相应的jndi属性
在start connector server前,先在系统属性中指定相应的jndi属性,start后再把这些属性恢复成原有属性
其中第一种方式不需要额外的代码,但是可能会对系统中其他jndi的InitialContext产生影响;第二种方式稍微麻烦点,但是在实现上比较完美。
值得提到的是,如果采用rmiregistry,并且rmiregistry和server在同一个JVM内,stub和rmiregistry可以共享一个端口。比如可以使用如下的JMX URL:
service:jmx:rmi://localhost:6000/jndi/rmi://localhost:6000/jmxrmi
但注意一定要在同一JVM内,比如先用LocateRegistry.createRegistry(6000)创建本地rmiregistry,再通过该URL开启connector server,则可以共享6000端口。
分享到:
相关推荐
通常,这需要在Tomcat的`catalina.sh`或`catalina.bat`启动脚本中添加JMX相关参数,以及在Zabbix的Java Gateway配置中设置正确的主机和端口信息。 最后,集成`cmdline-jmxclient-0.10.3.jar`和自定义模板到Zabbix的...
- 连接:通过`java -jar cmdline-jmxclient-0.10.3.jar [hostname]:[port]`命令连接到运行Tomcat的服务器,其中`[hostname]`是服务器IP,`[port]`是Tomcat的JMX端口,默认为8005。 - 查询:使用`-m`参数查询MBean...
脚本通常会扫描网络,查找暴露JMX端口的Tomcat服务器,并为每个发现的实例生成相应的监控配置。 Zabbix 是一款流行的开源监控解决方案,能够监控各种网络服务、硬件状态以及应用程序性能。将 `cmdline-jmxclient` ...
2. **连接到JMX服务器**:通过`cmdline-jmxclient`提供的命令行选项,指定JMX服务器的主机名、端口、认证凭据(如果需要)等信息建立连接。 3. **执行操作**:使用JMX MBean路径查询特定的MBean,获取其属性值,或者...
4. 命令行选项:cmdline-jmxclient-0.10.3可能提供一系列命令行参数,如指定服务器地址、端口、MBean的ObjectName、查询操作等。 5. 操作和属性:通过JMX,可以读取MBean的属性值、调用其操作,甚至订阅其通知。 6...
- RMI注册表:管理JMX连接器的地址和端口,便于客户端查找和连接。 - 安全性机制:提供安全策略和认证机制,确保只有授权的客户端才能访问远程MBean服务器。 这两个库在Java应用的管理和监控中扮演着重要角色,...
然后,通过`jconsole`或者其他JMX客户端连接到这个端口,就可以查看和操作MBeans了。 总之,JMXRI和JMXTools是Java应用程序管理和监控的重要组成部分,它们与日志库一起,构成了对系统健康状况进行跟踪和调整的基础...
4. `jmxri.properties`和`jmxtools.properties`:这些配置文件可能包含了JMX RMI的默认设置,如端口号和安全策略。 5. 文档和示例:可能还包括了关于如何使用这些工具和库的说明,以及演示如何配置和使用`...
4. **设置JMX连接器**:在`$CATALINA_BASE/conf/catalina.properties`中,添加或修改以下行,配置JMX连接器属性: ``` jmxRemotePasswordFile=$CATALINA_HOME/conf/jmxremote.password jmxRemoteAccessFile=$...
port JMX 服务器应该监听的端口。 默认值为5678 user用于身份验证的用户(连同密码) password用于身份验证的密码(然后也需要用户) 成功启动后,代理将打印出带有完整 URL 的成功消息,客户端可
3. **端口设置**: JMX默认使用随机端口,可通过`-Dcom.sun.management.jmxremote.port`指定固定端口。 4. **连接器配置**: 可以选择RMI、JNDI或者其他类型的JMX连接器。例如,使用RMI连接器需要设置`-Dcom.sun....
在Java HotSpot虚拟机中,使用开箱即用的远程jmx时会打开服务器端口,其中一些端口是动态的,这使防火墙非常难受。 下面显示了这一痛苦的事情: java \ -Djava.net.preferIPv4Stack=true \ -Dcom.sun....
Java Management Extensions(JMX)是Java平台上的一个标准技术,用于管理和监控应用程序、操作系统...通过深入研究这个"jmxremote-1_0-bin"包,你可以获得实现远程JMX连接所需的全部组件,进一步提升你的JMX实践技能。
jmx 实现远程连接tomcat jmx(Java Management Extensions)是一种Java技术,用于监控和管理Java应用程序。下面我们将详细介绍如何使用jmx实现远程连接tomcat。 一、配置环境 首先,我们需要确保Linux下配置好...
Eclipse 插件"JMX 连接工具"为开发者提供了一个便捷的途径,通过集成的开发环境来连接并管理JMX服务端,从而实现远程或本地的应用程序监控。 首先,JMX客户端连接信息是理解如何与JMX服务端建立通信的关键。JMX...
标题“cmdline-jmxclient.zip”指的是一个包含命令行界面的Java管理扩展(JMX)客户端工具,这个工具主要用于远程连接并监控Java虚拟机(JVM)以及运行在其中的应用,比如Tomcat服务器。JMX是一种Java平台提供的标准...
完成上述配置后,就可以使用之前获取的 JMX URL 来连接 TongWeb7 的 JMX 服务,例如 `service:jmx:rmi:///jndi/rmi://192.168.163.99:7200/jmxrmi`。你可以使用 Java 提供的 `jconsole` 工具,或者其他支持 JMX 的第...
默认情况下,这个 JMX Agent 的 RMI 端口是不加密的,并且没有进行身份验证,这意味着任何人都可以连接到该端口并对应用程序进行操作。 Java JMX Agent 安全性改进措施: 要改进 JMX Agent 的安全性,我们可以...
1. **连接**:使用JMX客户端连接到Zabbix监控的目标Java应用,通常需要指定应用的主机地址、端口以及认证信息(如果应用的MBean服务器需要)。 2. **查询**:通过指定MBean对象名,查询特定的监控项,比如内存使用...
* rmi.port:设置RMI连接的端口号,默认为60001。 * password.file:设置jmx.password文件的路径,用于存储jmx监控的密码。 * access.file:设置jmx.access文件的路径,用于存储jmx监控的权限配置。 在conf/...