一、 引言
首先我们要分析一个简单的web应用程序,它监控已经登陆的用户数目并通过一个安全的JMX服务来显示该项统计。我们还将运行这个应用程序的多个实例并且从所有的运行实例中跟踪这个统计数字。当然,你可以下载这个示例web应用程序。它需要你安装J2SE 5.0 SDK并且你的JAVA_HOME环境变量指向基安装目录。J2SE 5.0实现了1.2版本的JMX API和JMX 1.0版本的Remote API。同时还需要一个支持servlet的容器;我使用的是Apache Tomcat 5.5.12。另外,我还使用Apache Ant来构建这一示例应用程序。
二、 建立示例应用程序
首先,你要下载示例应用程序并且使用 ant war(更多的细节见build.xml中的注释)来创建一个WAR文件。把jmxapp.war复制到Tomcat的webapps目录。假定 Tomcat正在运行于你的本地机器的端口8080,那么该应用程序的URL将是:
http://localhost:8080/jmxapp
如果你看到一个提示你输入名字和口令的登陆屏幕,那么一切已经就绪了。
三、 跟踪一些有意义的数据
本文中的应用程序使用Struts框架来提交登录表单。一旦提交结束,即执行LoginAction.execute(..)方法-它将简单地检查是否用户的ID为"hello"以及是否其口令为"world"。如果二者都正确,那么登录成功并且控制被导向login_success.jsp;如果不正确,那么我们返回到登录表单。根据登录成功与否决定调用incrementSuccessLogins(HttpServletRequest)方法还是 incrementFailedLogins(HttpServletRequest)方法。现在,让我们先分析一下 incrementFailedLogins(HttpServletRequest):
| private void incrementFailedLogins(HttpServletRequest request) { HttpSession session = request.getSession(); ServletContext context =session.getServletContext(); Integer num = (Integer) context.getAttribute( Constants.FAILED_LOGINS_KEY); int newValue = 1; if (num != null) { newValue = num.intValue() + 1; } context.setAttribute( Constants.FAILED_LOGINS_KEY, new Integer(newValue)); } |
| public interface LoginStatsMBean { public int getFailedLogins(); public int getSuccessLogins(); } |
| public int getFailedLogins() { ServletContext context = Config.getServletContext(); Integer val = (Integer) context.getAttribute( Constants.FAILED_LOGINS_KEY); return (val == null) ? 0 : val.intValue(); } |
| public class JMXAgent { public JMXAgent() { //初始化JMX服务器 } public void start() { //启动JMX服务器 } //在应用程序结束时调用 public void stop() { //停止JMX服务器 } } |
| MBeanServer server = MBeanServerFactory.createMBeanServer(DOMAIN); server.registerMBean(new LoginStats(),new ObjectName(DOMAIN+ ":name=LoginStats")); |
| JMXServiceURL url = new JMXServiceURL("rmi",null, Constants.MBEAN_SERVER_PORT, "/jndi/rmi://localhost:" +Constants.RMI_REGISTRY_PORT +"/jmxapp"); |
| ServletContext context = Config.getServletContext(); //得到存储jmx用户信息的文件 String userFile =context.getRealPath("/")+"/WEB-INF/classes/"+Constants.JMX_USERS_FILE; //创建authenticator并且初始化RMI服务器 Map<string> env = new HashMap<string>(); env.put("jmx.remote.x.password.file", userFile); 现在,让我们创建JMXConnectorServer。下面一行代码完成这一功能: connectorServer = JMXConnectorServerFactory. newJMXConnectorServer(url, env, server); |
这个JMXConnectorServerFactory.newJMXConnectorServer(JMXServiceURL,Map, MBeanServer)方法使用我们刚创建的三个对象作为参数-它们是JMXServiceURL,存储认证信息的映射和MBeanServer。其中,connectorServer实例变量允许我们分别在应用程序启动和停止时,分别用start()和stop()来启动和停止 JMXConnectorServer。
提示 尽管JSR 160的J2SE 5.0实现相当有力;但是另外的实现,例如MX4J,也提供了一些类-它们提供了方便的特性,例如口令混淆,也就是PasswordAuthenticator类。
七、 启动RMI注册
在早些时候,我提到RMI注册并且指出当访问服务时执行一个JNDI查询。然而,现在我们没有一个正运行的RMI注册,因此一个JNDI查询将失败。一个RMI注册的启动可以用手工方式或编程方式来实现。
(一) 使用命令行
在你的Windows或Linux命令行上,输入下列一名来启动一个RMI注册:
rmiregistry &
这将启动你的默认主机和端口(分别是localhost和1109)的RMI注册。然而,对于我们的web应用程序来说,我们不可能依赖一个在应用程序启动时可用的RMI而宁愿用编程方式来实现之。
(二) 以编程方式启动RMI注册
为了以编程方式启动RMI注册,你可以使用LocateRegistry.createRegistry(int port)方法。该方法返回类型注册的一个对象。当我们想在应用程序一端终止这个注册时,我们保存这个参考。就在我们启动我们的在 JMXAgent.start()中的JMXConnectorServer之前,我们首先启动RMI注册,使用下列代码行:
registry = LocateRegistry.createRegistry(Constants.RMI_REGISTRY_PORT);
在应用程序一端,在JMXAgent.stop()中停止JMXConnectorServer之后,调用下列方法来终止该注册:
UnicastRemoteObject.unexportObject(registry,true);
注意,StartupListener类触发了应用程序开始和结束任务。
八、 访问我们的JMX服务
我们可以有好几种方法来存取JSR 160服务。为此,我们可以通过编程或通过使用一个GUI来实现。
(一) 使用MC4J连接
通过把jmxapp.war复制到Tomcat的webapps目录来发布该应用程序。下载并且安装MC4J。一旦安装完,创建一新的类型JSR 160的服务器连接并且指定该服务器URL-它在应用程序启动时在应用程序服务器日志中打印。在我的示例中,它是:
service:jmx:rmi://zarar:9589/jndi/rmi://localhost:1100/jmxapp
提供用户名和口令,MC4J分别把它们参考为"Principle"和"Credentials"。点击Next将把你带到一个屏幕-在此你可以定制你的classpath。默认设置应该工作正常,并且你可以点击"Finish"来连接到该JMX服务。一旦建立连接,浏览如图1所示的MC4J树结构,直到你找到LoginStats MBean实现的"Properties"选项。
![]() 图1.MC4J视图 |
![]() 图2.属性窗口 |
![]() 图3."添加应用程序"页面 |
![]() 图4.添加应用程序簇页面 |
![]() 图5.针对jmxapp和jmxapp2的簇视图 |
(责任编辑:城尘)
|
|||
| · 我是黑客我怕谁——讲.. · ARP攻击防范与解决方案 · Solaris 10 配置管理 · Solaris基础知识入门 · RIP路由协议专栏 · MPLS路由协议专栏 · OSPF路由协议专栏 · 思科路由器产品 |
· 华为路由器产品 · 路由器模拟器 · AIX操作系统管理应用(.. · 思科路由器配置 · 路由器组网解决方案 · 路由器密码恢复 · 无线路由器故障处理 · 路由故障处理手册 |
||
|
|||
| · Java基础教程 · VPN技术 · SQL Server 2005全解 · ARP攻击防范与解决方案 · SOA 面向服务架构 · SQL Server 2005全解 · Java编程开发手册 · 三层交换技术专题 |
· SQL Server入门到精通 · Windows Server 2003企.. · Windows远程桌面应用 · C#技术开发指南 · VPN技术 · Solaris 10 配置管理 · C#技术开发指南 · Windows操作系统安装 |
||
|
|||
| · ARP攻击防范与解决方案 · VPN技术 · SQL Server 2005全解 · Java基础教程 · SQL Server入门到精通 · SQL Server 2005全解 · SOA 面向服务架构 · Java编程开发手册 |
· C#技术开发指南 · 三层交换技术专题 · C#技术开发指南 · Windows远程桌面应用 · Windows Server 2003企.. · 邮件服务器专题 · wimax技术与趋势 · Windows操作系统安装 |
||
| ·DB2 Viper快速入门 ·DB2 9数据库的镜像分割与.. |
·将XML应用程序从DB2 8.x.. ·DB2 9中的pureXML:如何.. |
| ·服务器中的“傻瓜机”在.. ·盖茨也喜欢登录Youtube看.. |
· · |
| ·网名接龙--之大话黄琨 ^o^ ·ARP欺骗引发的“冤案”—.. |
·ARP欺骗的原理、步骤和危.. ·利用负载均衡技术针对Web.. |
| ·VMware Workstation 6.01.. ·Windows Server 2008 RC0.. |
·ISA Server 2006的全自动.. ·ISA Server、虚拟机、托.. |
| · NGN:下一代网络 · 网络访问中断大排查 · FTTx光纤接入 |
· IT基础教程 · 平凡黑客讲述精彩人生(.. · 平凡黑客讲述精彩人生(.. |
| · C++是垃圾语言?! · 2007年IT界七大抄袭事件 · Java实用开发全集 |
· 解析Ajax开发框架 走进A.. · 基于Google Maps与Ajax.. · 基于Google Maps与Ajax.. |
| · 热门 IT 培训认证官方资.. · Ubuntu 中文开源频道 · Solaris基础知识入门 |
· AMD三核心处理器解析 痛.. · 服务器基础知识入门 · Rambus第二?看全缓冲内.. |
| · 甲骨文Oracle 11g正式发.. · Oracle数据库开发之PL/S.. · Oracle数据库开发基础教.. |
· 存储2006,一个并购的大.. · IDC宣布浪潮蝉联存储市.. · 双机热备技术 |