• 监控Tomcat解决方案(监控应用服务器系列文章分享)


    使用JMX接口开发监控程序
      ◆ 全部代码需要从零开始,代码量较大
      ◆ 支持各不同版本比较麻烦,每个版本可能有差异
      ◆ 可支配性强
      ◆ 最重要的一个缺点是,配置比较麻烦

    Tomcat激活JMX远程配置

    ① ■ 先修改Tomcat的启动脚本,window下tomcat的bin/catalina.bat(linux为catalina.sh),添加以下内容,8999是jmxremote使用的端口号,第二个false表示不需要鉴权:

    set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
    set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG%

    可以加在if "%OS%" == "Windows_NT" setlocal 一句后的大段的注释后面。

    参考官方说明:
        http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html#Enabling_JMX_Remote

    ② ■ 上面的配置是不需要鉴权的,如果需要鉴权则添加的内容为:

    set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access
    set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG%


      然后复制并修改授权文件,$JAVA_HOME/jre/lib/management下有jmxremote.access和jmxremote.password的模板文件,将两个文件复制到$CATALINA_BASE/conf目录下
      ● 修改$CATALINA_BASE/conf/jmxremote.access 添加内容:
         monitorRole readonly
         controlRole readwrite

      ● 修改$CATALINA_BASE/conf/jmxremote.password 添加内容:
         monitorRole tomcat
         controlRole tomcat

    注意:如果只做第一步没有问题,进行了第二步Tomcat就启动不了,那么很可能是密码文件的权限问题
        需要修改jmxremote.password文件的权限,只有运行Tomcat的用户有访问权限
        Windows的NTFS文件系统下,选中文件,点右键 -->“属性”-->“安全”--> 点“高级”--> 点“更改权限”--> 去掉“从父项继承....”--> 弹出窗口中选“删除”,这样就删除了所有访问权限。再选“添加”--> “高级”--> “立即查找”,选中你的用户,例administrator,点“确定",“确定"。来到权限项目窗口,勾选“完全控制”,点“确定”,OK了。

    官方的提示:
        The password file should be read-only and only accessible by the operating system user Tomcat is running as. 

    ③ ■ 重新启动Tomcat,在Windows命令行输入“netstat -ano”查看配置的端口号是否已打开,如果打开,说明上面的配置成功了。

    ④ ■ 使用jconsole测试JMX。

       运行$JAVA_HOME/bin目录下的jconsole.exe,打开J2SE监视和管理控制台,然后建立连接,如果是本地的Tomcat则直接选择然后点击连接,如果是远程的,则进入远程选项卡,填写地址、端口号、用户名、口令即可连接。Mbean属性页中给出了相应的数据,Catalina中是tomcat的,java.lang是jvm的。对于加粗的黑体属性值,需双击一下才可看内容。

    遇到的几个问题:

    1.tomcat必须要用命令或者startup.bat启动,jconsole才能连接成功。

    2.尽量用第一种方式配置,但是要把密码文件拷贝到tomcat-conf目录下,设置密码和口令。

    3.tomcat必须配置环境变量,如有多个tomcat同一台服务器上,则添加一个CATALINA_HOME2,然后把tomcat下面catalina.bat和startup.bat中所有CATALINA_HOME替换为CATALINA_HOME2.

    实例代码:

    package com.gsww.jup.controller.chatShowController;

    import java.lang.management.MemoryUsage;
    import java.text.DecimalFormat;
    import java.util.ArrayList;
    import java.util.Formatter;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    import javax.management.MBeanServerConnection;
    import javax.management.ObjectName;
    import javax.management.openmbean.CompositeDataSupport;
    import javax.management.remote.JMXConnector;
    import javax.management.remote.JMXConnectorFactory;
    import javax.management.remote.JMXServiceURL;
    import javax.servlet.ServletRequest;
    import javax.servlet.http.HttpServletRequest;

    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;


    import com.gsww.jup.controller.BaseController;

    @Controller
    @RequestMapping(value = "/applicationServerMonitoring")
    public class ApplicationServerMonitoringController extends BaseController{


    @RequestMapping(value = "/serverList",method = RequestMethod.GET)
    public String serverList(Model model,ServletRequest request,HttpServletRequest hrequest) {
    try{
    List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();

    Map<String,Object> map=getMap("61.178.5.73","8092");
    map.put("server", "客户端接口服务1");

    Map<String,Object> map1=getMap("10.18.23.218","8088");
    map1.put("server", "客户端接口服务2");

    Map<String,Object> map2=getMap("127.0.0.1","7999");
    map2.put("server", "心跳接口服务");

    Map<String,Object> map3=getMap("127.0.0.1","8999");
    map3.put("server", "后台服务");

    list.add(map);
    list.add(map1);
    list.add(map2);
    list.add(map3);
    model.addAttribute("list", list);

    }catch(Exception ex){
    ex.printStackTrace();
    }
    return "chatShow/serverMonitor_list";
    }
    public Map<String, Object> getMap(String ip,String port){
    Map<String, Object> serverMap=new HashMap<String, Object>();
    try {
    String jmxURL = "service:jmx:rmi:///jndi/rmi://"+ip+":"+port+"/jmxrmi";//tomcat jmx url
    JMXServiceURL serviceURL = new JMXServiceURL(jmxURL);

    Map map = new HashMap();
    String[] credentials = new String[] { "monitorRole" , "QED" };
    map.put("jmx.remote.credentials", credentials);
    JMXConnector connector = JMXConnectorFactory.connect(serviceURL, map);
    MBeanServerConnection mbsc = connector.getMBeanServerConnection();


    //------------------------ JVM -------------------------
    //堆使用率
    ObjectName heapObjName = new ObjectName("java.lang:type=Memory");
    MemoryUsage heapMemoryUsage = MemoryUsage.from((CompositeDataSupport)mbsc.getAttribute(heapObjName, "HeapMemoryUsage"));
    long maxMemory = heapMemoryUsage.getMax();//堆最大
    long commitMemory = heapMemoryUsage.getCommitted();//堆当前分配
    long usedMemory = heapMemoryUsage.getUsed();
    System.out.println("推最大:"+maxMemory);
    System.out.println("堆当前分配:"+commitMemory);
    System.out.println("堆使用:"+usedMemory);
    System.out.println("heap:"+(double)usedMemory*100/commitMemory+"%");//堆使用率
    serverMap.put("maxMemory", format((double)maxMemory/1000000)+"M");
    serverMap.put("commitMemory", format((double)commitMemory/1000000)+"M");
    serverMap.put("usedMemory", format((double)usedMemory/1000000)+"M");
    serverMap.put("usedPersent", format((double)usedMemory*100/commitMemory)+"%");

    return serverMap;
    } catch (Exception e) {
    serverMap.put("maxMemory", "--");
    serverMap.put("commitMemory", "--");
    serverMap.put("usedMemory", "--");
    serverMap.put("usedPersent", "100.00%");
    return serverMap;
    }
    }

    public String formatTimeSpan(long span){
    long minseconds = span % 1000;

    span = span /1000;
    long seconds = span % 60;

    span = span / 60;
    long mins = span % 60;

    span = span / 60;
    long hours = span % 24;

    span = span / 24;
    long days = span;
    return (new Formatter()).format("%1$d天 %2$02d:%3$02d:%4$02d.%5$03d", days,hours,mins,seconds,minseconds).toString();
    }
    public String format(double s) {
    DecimalFormat df = new DecimalFormat("#.##");
    return df.format(s);
    }

    }

  • 相关阅读:
    LG7124 [Ynoi2008] stcm【树分治,构造】
    美团杯 2021【杂题】
    UOJ455【UER #8】雪灾与外卖【反悔贪心,模拟费用流】
    js正则匹配正负小数
    iview table 自适应高度
    iview tree render 自定义右键菜单(解决部分场景下官网tree右键菜单bug)
    iTextSharp Image.ScaleToFit自适应缩放简述
    C# 从动态类型中获取集合
    Js自定义日期
    SVN代码统计工具(资源下载+使用命令)
  • 原文地址:https://www.cnblogs.com/wjwen/p/4829932.html
Copyright © 2020-2023  润新知