JMX,Jstatd做好JVM应用上线的最后一层保障

一个成功的java项目标准并不仅仅是业务功能实现,但是纵观国内,很多项目组在前期项目开发设计中只考虑了业务功能,没有考虑项目后期维护的监控设计。没有完善的监控运维设计,项目存活的寿命应该也不长吧?好的项目能够吸引人留下来,并不断强化项目的功能优化每一处代码,坏的项目只会逼死人,不断的增加龌龊代码以至于根本无法维护。 当然从公司来说,业务的首要实现是公司能够赚钱的有效保障,公司赚不了钱了,写的在好的代码也只能静静的躺在硬盘中。我想一个负责的开发人员不仅要能重视业务功能的实现,还能保证在项目上线运维中针对突发情况做到监控。 我理解的监控

我理解的监控分两种,一种是运维的监控-监控整个集群的各项资源的使用情况以及各个服务的存活情况,另一种是开发的监控-监控代码问题导致的线程死锁,OOM等,以及业务消息的历史可回溯。
我是一名开放,这里主要讲讲我的心得,开发中的监控。如何减少开发人员不必要的加班。

代码异常监控 应用代码在面对线上各种请求时,经常会发生死锁,OOM等问题。这个时候我们如何去查看呢? 如果我们不想连上远程服务器,通过本地的一些可视化工具连接远程程序,查看远程程序的线程,CPU,GC,堆内存等使用情况。 远程主机配置jmx 这里只是演示JMX的监控功能,JMX还有动态修改bean属性等功能不在这一篇文章讲解。

修改密码,找到配置文件$JAVA_HOME/jre/lib/management/jmxremote.password.template,复制一份并改名为jmxremote.password,然后修改只读权限并编辑jmxremote.passwrod,取消以下两行注释:

#monitorRole QED #controlRole R&D 修改要启动的java程序启动参数(JVM_OPTS)。 打开tomcat的bin目录下的catalina.sh,加入以下内容**(非tomcat程序也类似)** JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=192.168.19.131 -Dcom.sun.management.jmxremote.port=18999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

参数authenticate表示是否需要密码认证,赋值为true就会使用jmxremote.password设置的密码。

修改文件权限 监控的程序是由哪个用户启动,则把jmxremote.password文件的权限改为这个用户的只读权限,否则启动程序会报错:Error: Password file read access must be restricted。这些在jmxremote.password里的注释都有说明。比如,如果你是用intsmaze用户启动java程序 chown intsmaze jmxremote.password chmod 400 jmxremote.password 启动jvisualvm

先启动待监控的程序

sh startup.sh

左边栏,右键“远程”>>“添加远程主机”

JMX,Jstatd做好JVM应用上线的最后一层保障

左侧栏,右键刚才添加的远程主机>>“添加jmx链接”,使用配置的端口

JMX,Jstatd做好JVM应用上线的最后一层保障


JMX,Jstatd做好JVM应用上线的最后一层保障


如果我们不配置JVM_OPTS参数,那么我们在本地使用javaVisualVM是无法访问远程服务器上的tomcat服务的状况,要想知道远程服务器的状况就必须使用CRT等工具连上服务器使用linux命令去查看程序的运行情况。

监控服务器上的java程序

在java -cp 命令中加入如下参数即可

java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=22222 -cp jmx.jar cn.intsmaze.thread.TestDeadThread

TestDeadThread类如下

public class TestDeadThread implements Runnable { int a, b; public TestDeadThread(int a, int b) { this.a = a; this.b = b; } public void run() { synchronized (Integer.valueOf(a)) { synchronized (Integer.valueOf(b)) { System.out.println(a + b); } } } public static void main(String[] args) throws InterruptedException { Thread.sleep(3000); for (int i = 0; i < 100; i++) { new Thread(new TestDeadThread(1, 2)).start(); new Thread(new TestDeadThread(2, 1)).start(); } } } JvisiualVM通过JMX的方式连接到远程服务器上的JVM,此时能获取到JVM的基本信息(启动参数、系统属性)、CPU使用情况、堆内存整体情况以及线程的整体情况等。但如果想通过Visual GC插件进一步了解堆内各区的情况的话,就会发现插件此时并不工作。

JMX,Jstatd做好JVM应用上线的最后一层保障


Visual GC插件不工作,是因为此插件使用的协议是RMI,因此需要使用下面的jstatd方式进行连接。

jstatd 连接到远程JVM JVM jstat Daemon:守护进程,一个RMI服务器程序,用于监控本地所有JVM从创建开始直到销毁整个过程中的资源使用情况,同时提供接口给监控工具(如这里的VisualVM),让工具能连接到本机所有的JVM。 启动jstatd服务 ${java_home}/bin目录下启动jstatd服务 [intsmaze@centos-Reall-131 bin]./jstatd Could not create remote object access denied ("java.util.PropertyPermission" "java.rmi.server.ignoreSubClasses" "write") java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.rmi.server.ignoreSubClasses" "write") at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) at java.security.AccessController.checkPermission(AccessController.java:884) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at java.lang.System.setProperty(System.java:792) at sun.tools.jstatd.Jstatd.main(Jstatd.java:139) 由于jstatd server没有提供任何对远程client端的认证,客户端程序获取到本地当前用户的所有JVM信息后可能存在安全隐患,所以jstatd要求启动之前必须指定本地安全策略,否则jstatd进程无法启动,抛出上面错误。 创建安全策略文件 在需要被监控的远程主机创建一个安全策略文件,比如保存为/home/intsmaze/jdk1.8.0_144/bin/jstatd-all.policy,内容如下: grant codebase "file:/home/intsmaze/jdk1.8.0_144/lib/tools.jar" { permission java.security.AllPermission; }; 启动jjstatd带参数

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjxfj.html