北京人妖龚景旋:JMX远程控制
来源:百度文库 编辑:偶看新闻 时间:2024/05/01 10:18:14
问题背景讨论:在JAVA运行时,对JVM系统的检测、管理是开发同学一直期望的,目前有一些开源产品开源针对JVM进行监控,例如javamelody等等,这样框架虽然好,但是如果使用会带来一些问题。第一:由于javamelody入口是一个filter,所以会带来性能问题、第二:如果应用服务器很多,会缺乏统一管理,此外安全性、爬虫等等问题略过不提
JDK自带了故障检测工具Jconsole和1.6出来的Jvisualvm都可以远程对服务器进行监控,后者甚是提供可以在线得到ThreadDump和HeapDump文件,更是提供了可扩展插件功能(虽然可能会影响jvm服务器性能)
但现状很多公司都有自己的运维团队,未必会把线上服务器的权限交给我们开发同学,所以有必要了解JAVA远程管理方面的知识,假设如果在后台有一套系统,可以管理、监控我们线上所有java服务器,如果出现问题不需要对每个服务器进行排查而是直接从列表中获取、定位到信息,岂不是一件很幸福的事情~
书归正文,分享下近几天在JMX方面的知识,JDK的API中翻译过来对javax.management的描述
提供 Java Management Extensions 的核心类。
Java Management Extensions (JMXTM) API 是一个用于管理和监视的标准 API。典型用途包括:
1) 查询并更改应用程序配置
2) 累积有关应用程序行为的统计数据并使其可用
3) 通知状态更改及错误状况。
4) JMX API 还可以作为解决方案的一部分来管理系统、网络等。
5) API 包括远程访问,远程管理程序可以基于这些目的与正在运行的应用程序进行交互。
JMX核心类为Mbean。MBean 是表示资源的指定管理对象。它有一个管理接口,该接口包括以下内容:
1) 可以读取和/或写入的指定名称和类型的属性
2) 可以调用的指定名称和类型的操作
3) 可以由 MBean 发送的指定类型的通知。
推荐一篇文章可以让大家入门
http://www.ibm.com/developerworks/cn/java/j-lo-jse63/
配置远程连接tomcat需要在tomcat所在服务器修改几个配置
1) 修改JMX配置
进入JAVA_HOME/jre/lib/management路径下面
将jmxremote.password.template改成jmxremote.password,将内容中的monitorRole QED的注释去掉
将management.properties中的com.sun.management.jmxremote.port=(改成你想要的JMX端口号)
将 com.sun.management.jmxremote.ssl=false、 com.sun.management.jmxremote.authenticate=false注释打开
注意:linux下需要该权限,chmod 600 jmxremote.access, chmod 600 jmxremote.password
window下特麻烦,现需要jdk装在NTFS文件系统下,选中文件,点右键“属性”-〉安全,点“高级”,去掉“从父项继承....”,弹出窗口中选“删除”,这样删除了所有访问权限。再选“添加”-〉高级,“立即查找”,选中你的用户,例administrator,点“确定",“确定"。来到权限窗口,勾选"完全控制",点"确定",OK了。
用jconsole连接远程linux服务时, IP地址和port都输入正确的情况下,仍然是连接失败
vi /etc/hosts,将hostname对应的ip改为真实ip
2) 修改tomcat启动参数
windows下面为catalina.bat、linux下面为cataina.sh
set CATALINA_OPTS=-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port="JMXport"
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
如果不修改的时候默远程连接不上,远程连接的通过IP和JMX端口找到JVM虚拟机后无法定位具体哪个应用使用JMX端口,所以只有在启动tomcat情况后占用JMX
关于配置JMX,可以具体参考http://download.oracle.com/javase/1.5.0/docs/guide/management/agent.html#remote
实战远程连接TOMCAT
1) 获取连接
Java代码
2) 获取所有的objectName
Java代码
3) 获取堆内存信息
Java代码
4) 获取堆中伊甸区
Java代码
5) 获取线程
Java代码
由于可以获取的信息很多,暂不全部列出来
翻过头来看下tomcat对JMX的支持
看完上面最后一段话,有没有一种很雷人的感觉
关于tomcat对JMX的支持可以看下详细的文档
http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html
当我们默认直接访问tomcat提供的JMX接口时(http://localhost:8080/manager/jmxproxy/?qry=)会出现所有的MBeans,
如果想要具体的MBeans只需要将其name后面的值放在url的后面
因此,在默认情况下我们看到的信息都可以通过远程方式获取到,下一篇会介绍如何远程管理Tomcat
JDK自带了故障检测工具Jconsole和1.6出来的Jvisualvm都可以远程对服务器进行监控,后者甚是提供可以在线得到ThreadDump和HeapDump文件,更是提供了可扩展插件功能(虽然可能会影响jvm服务器性能)
但现状很多公司都有自己的运维团队,未必会把线上服务器的权限交给我们开发同学,所以有必要了解JAVA远程管理方面的知识,假设如果在后台有一套系统,可以管理、监控我们线上所有java服务器,如果出现问题不需要对每个服务器进行排查而是直接从列表中获取、定位到信息,岂不是一件很幸福的事情~
书归正文,分享下近几天在JMX方面的知识,JDK的API中翻译过来对javax.management的描述
提供 Java Management Extensions 的核心类。
Java Management Extensions (JMXTM) API 是一个用于管理和监视的标准 API。典型用途包括:
1) 查询并更改应用程序配置
2) 累积有关应用程序行为的统计数据并使其可用
3) 通知状态更改及错误状况。
4) JMX API 还可以作为解决方案的一部分来管理系统、网络等。
5) API 包括远程访问,远程管理程序可以基于这些目的与正在运行的应用程序进行交互。
JMX核心类为Mbean。MBean 是表示资源的指定管理对象。它有一个管理接口,该接口包括以下内容:
1) 可以读取和/或写入的指定名称和类型的属性
2) 可以调用的指定名称和类型的操作
3) 可以由 MBean 发送的指定类型的通知。
推荐一篇文章可以让大家入门
http://www.ibm.com/developerworks/cn/java/j-lo-jse63/
配置远程连接tomcat需要在tomcat所在服务器修改几个配置
1) 修改JMX配置
进入JAVA_HOME/jre/lib/management路径下面
将jmxremote.password.template改成jmxremote.password,将内容中的monitorRole QED的注释去掉
将management.properties中的com.sun.management.jmxremote.port=(改成你想要的JMX端口号)
将 com.sun.management.jmxremote.ssl=false、 com.sun.management.jmxremote.authenticate=false注释打开
注意:linux下需要该权限,chmod 600 jmxremote.access, chmod 600 jmxremote.password
window下特麻烦,现需要jdk装在NTFS文件系统下,选中文件,点右键“属性”-〉安全,点“高级”,去掉“从父项继承....”,弹出窗口中选“删除”,这样删除了所有访问权限。再选“添加”-〉高级,“立即查找”,选中你的用户,例administrator,点“确定",“确定"。来到权限窗口,勾选"完全控制",点"确定",OK了。
用jconsole连接远程linux服务时, IP地址和port都输入正确的情况下,仍然是连接失败
vi /etc/hosts,将hostname对应的ip改为真实ip
2) 修改tomcat启动参数
windows下面为catalina.bat、linux下面为cataina.sh
set CATALINA_OPTS=-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port="JMXport"
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
如果不修改的时候默远程连接不上,远程连接的通过IP和JMX端口找到JVM虚拟机后无法定位具体哪个应用使用JMX端口,所以只有在启动tomcat情况后占用JMX
关于配置JMX,可以具体参考http://download.oracle.com/javase/1.5.0/docs/guide/management/agent.html#remote
实战远程连接TOMCAT
1) 获取连接
Java代码
- private static void getConnection() throws Exception {
- //用户名、密码
- Map
map = new HashMap (); - map
- .put("jmx.remote.credentials", new String[] { "monitorRole",
- "QED" });
- String jmxURL = "service:jmx:rmi:///jndi/rmi://192.168.0.100:1000/jmxrmi";
- JMXServiceURL serviceURL = new JMXServiceURL(jmxURL);
- connector = JMXConnectorFactory.connect(serviceURL, map);
- mbsc = connector.getMBeanServerConnection();
- }
2) 获取所有的objectName
Java代码
- Set MBeanset = mbsc.queryMBeans(null, null);
- Iterator MBeansetIterator = MBeanset.iterator();
- while (MBeansetIterator.hasNext()) {
- ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator
- .next();
- ObjectName objectName = objectInstance.getObjectName();
- MBeanInfo objectInfo = mbsc.getMBeanInfo(objectName);
- System.out.print("ObjectName:" + objectName.getCanonicalName()
- + ".");
- System.out.print("mehtodName:");
- for (int i = 0; i < objectInfo.getAttributes().length; i++) {
- System.out.print(objectInfo.getAttributes()[i].getName() + ",");
- }
- System.out.println();
- }
3) 获取堆内存信息
Java代码
- ObjectName heapObjName = new ObjectName("java.lang:type=Memory");
- //堆内存
- MemoryUsage heapMemoryUsage = MemoryUsage
- .from((CompositeDataSupport) mbsc.getAttribute(heapObjName,
- "HeapMemoryUsage"));
- long commitMemory = heapMemoryUsage.getCommitted();// 堆当前分配
- long usedMemory = heapMemoryUsage.getUsed();
- System.out.print("堆内存总量:"+heapMemoryUsage.getMax()/1024+"KB,当前分配量:"+commitMemory/1024+"KB,当前使用率:"+usedMemory/1024+"KB,");
- System.out.println("堆内存使用率:" + (int) usedMemory * 100
- / commitMemory + "%");// 堆使用率
- //栈内存
- MemoryUsage nonheapMemoryUsage = MemoryUsage
- .from((CompositeDataSupport) mbsc.getAttribute(heapObjName,
- "NonHeapMemoryUsage"));
- long noncommitMemory = nonheapMemoryUsage.getCommitted();
- long nonusedMemory = heapMemoryUsage.getUsed();
- System.out.println("栈内存使用率:" + (int) nonusedMemory * 100
- / noncommitMemory + "%");
- //PermGen内存
- ObjectName permObjName = new ObjectName(
- "java.lang:type=MemoryPool,name=Perm Gen");
- MemoryUsage permGenUsage = MemoryUsage
- .from((CompositeDataSupport) mbsc.getAttribute(permObjName,
- "Usage"));
- long committed = permGenUsage.getCommitted();// 持久堆大小
- long used = heapMemoryUsage.getUsed();//
- System.out.println("perm gen:" + (int) used * 100 / committed
- + "%");// 持久堆使用率
4) 获取堆中伊甸区
Java代码
- ObjectName youngHeapObjName = new ObjectName("java.lang:type=MemoryPool,name=Eden Space");
- // 获取Mbean对象
- MBeanInfo youngHeapInfo = mbsc.getMBeanInfo(youngHeapObjName);
- // 获取对象的属性
- MBeanAttributeInfo[] youngHeapAttributes = youngHeapInfo.getAttributes();
- MemoryUsage youngHeapUsage = MemoryUsage
- .from((CompositeDataSupport) mbsc.getAttribute(youngHeapObjName, "Usage"));
- System.out.print("目前新生区分 配最大内存:"+youngHeapUsage.getMax()/1024+"KB,");
- System.out.print("新生区已分配:"+youngHeapUsage.getCommitted()/1024+"KB,");
- System.out.print("新生区初始化:"+youngHeapUsage.getInit()/1024+"KB,");
- System.out.println("新生区已使用"+youngHeapUsage.getUsed()/1024+"KB");
5) 获取线程
Java代码
- ObjectName managerObjName = new ObjectName(
- "Catalina:type=Manager,*");
- Set
s = mbsc.queryNames(managerObjName, null); - for (ObjectName obj : s) {
- ObjectName objname = new ObjectName(obj.getCanonicalName());
- System.out.print("objectName:"+objname);
- System.out.print(",最大会话数:"
- + mbsc.getAttribute(objname, "maxActiveSessions")+",");
- System.out.print("会话数:"
- + mbsc.getAttribute(objname, "activeSessions")+",");
- System.out.println("活动会话数:"
- + mbsc.getAttribute(objname, "sessionCounter"));
由于可以获取的信息很多,暂不全部列出来
翻过头来看下tomcat对JMX的支持
看完上面最后一段话,有没有一种很雷人的感觉
关于tomcat对JMX的支持可以看下详细的文档
http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html
当我们默认直接访问tomcat提供的JMX接口时(http://localhost:8080/manager/jmxproxy/?qry=)会出现所有的MBeans,
如果想要具体的MBeans只需要将其name后面的值放在url的后面
因此,在默认情况下我们看到的信息都可以通过远程方式获取到,下一篇会介绍如何远程管理Tomcat