1. 程式人生 > >JMX實現遠端伺服器Tomcat系統監控之三

JMX實現遠端伺服器Tomcat系統監控之三

前面兩篇JMX遠端監控Tomcat伺服器是沒配置密碼的,下面介紹在Tomcat監控時配置使用者密碼。

具體Tomcat地址:http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html#Enabling_JMX_Remote

Note: This syntax is for Microsoft Windows. The command has to be on the same line. It is wrapped to be more readable. If Tomcat is running as a Windows service, use its configuration dialog to set java options for the service. For un*xes remove"set "

from beginning of the line.

set CATALINA_OPTS=-Dcom.sun.management.jmxremote
  -Dcom.sun.management.jmxremote.port=%my.jmx.port%
  -Dcom.sun.management.jmxremote.ssl=false
  -Dcom.sun.management.jmxremote.authenticate=false
  1. If you require authorization, add and change this :
      -Dcom.sun.management.jmxremote.authenticate=true
      -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password
      -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access
    
  2. edit the access authorization file $CATALINA_BASE/conf/jmxremote.access :
    monitorRole readonly
    controlRole readwrite
    
  3. edit the password file $CATALINA_BASE/conf/jmxremote.password :
    monitorRole tomcat
    controlRole tomcat
    
    Tip: The password file should be read-only and only accessible by the operating system user Tomcat is running as.
其內容大概如下:

   1、編輯Tomcat/bin中的catalina.bat。如果配置許可權,需要將autenticate設定為true,將1中的下面兩行程式碼新增到最上面一行,注意:這些所有的命令必須在一行!。

   2、在Tomcat/conf目錄下新建兩個檔案:jmxremote.accessjmxremote.password

          第一個檔案存的是角色資訊,第二個存放的是密碼資訊(可修改)。

配置完上面資訊後:我們啟動tomcat時,Tomcat出現一閃而過,上面提示的大概意思是許可權問題。

     解決的辦法是:選中Tomcat資料夾,點右鍵 -->“屬性”-->“安全”--> 點“高階”--> 點“更改許可權”--> 去掉“從父項繼承....”--> 彈出視窗中選“刪除”,這樣就刪除了所有訪問許可權。再選“新增”--> “高階”--> “立即查詢”,選中你的使用者(或使用者組,如果選使用者不行那就選使用者組),例administrator(當前電腦的許可權),點“確定",“確定"。來到許可權專案視窗,勾選“完全控制”,點“確定”,重啟就可以了。

實現:

  沒有密碼時,我們採用JMXConnectorFactory工廠類的 connect(JMXServiceURL serviceURL) 建立到位於給定地址的聯結器伺服器的連線。 設定密碼後需connect(JMXServiceURL serviceURL, Map<String,?> environment) ,

  設定map存放environment.put("jmx.remote.credentials", credentials);配置資訊。

      String[] credentials = new String[] { "monitorRole", "tomcat" };

其具體實現如下:

package pyc.jvm.monitor;

import java.io.IOException;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.ThreadMXBean;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.ReflectionException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

/**
 * 建立時間:2014-12-5 上午11:06:34
 * 
 * @author zhangtianyou
 * @version 2.2
 */

public class JMXTest3 {

	private final static String SERVICE_1 = "service:jmx:rmi:///jndi/rmi://192.168.85.54:8787/jmxrmi";

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		// 10秒呼叫一次
		Timer timer = new Timer();
		timer.schedule(new JMXTest3().new MonitorTask(SERVICE_1), 0, 10000);

	}

	private class MonitorTask extends TimerTask {

		private String service;

		public MonitorTask(String service) {
			this.service = service;
		}

		@Override
		public void run() {

			JMXmonitor(service);
		}

	}

	private static void JMXmonitor(String service) {
		JMXConnector jmxConnector = null;

		try {
			JMXServiceURL ServiceURL = new JMXServiceURL(service);
			Map<String, String[]> environment = new HashMap<String, String[]>();
			// 使用者名稱密碼,在jmxremote.password檔案中的密碼
			String[] credentials = new String[] { "monitorRole", "tomcat" };
			environment.put("jmx.remote.credentials", credentials);
			jmxConnector = JMXConnectorFactory.connect(ServiceURL, environment);

			MBeanServerConnection mBeanServerConnection = jmxConnector
					.getMBeanServerConnection();

			// 獲取MemoryMXBean
			System.out.println("\nMemory");
			MemoryMXBean memoryMXBean = ManagementFactory
					.newPlatformMXBeanProxy(mBeanServerConnection,
							ManagementFactory.MEMORY_MXBEAN_NAME,
							MemoryMXBean.class);

			MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
			System.out.println("heapMemoryUsage :");
			System.out.println("committed = "
					+ convertKB(heapMemoryUsage.getCommitted()));
			System.out
					.println("init = " + convertKB(heapMemoryUsage.getInit()));
			System.out.println("max = " + convertKB(heapMemoryUsage.getMax()));
			System.out
					.println("used = " + convertKB(heapMemoryUsage.getUsed()));

			MemoryUsage nonHeapMemoryUsage = memoryMXBean
					.getNonHeapMemoryUsage();
			System.out.println("\nnonHeapMemoryUsage :");
			System.out.println("committed = "
					+ convertKB(nonHeapMemoryUsage.getCommitted()));
			System.out.println("init = "
					+ convertKB(nonHeapMemoryUsage.getInit()));
			System.out.println("max = "
					+ convertKB(nonHeapMemoryUsage.getMax()));
			System.out.println("used = "
					+ convertKB(nonHeapMemoryUsage.getUsed()));

			// 獲取 ThreadMXBean
			System.out.println("\nThread");
			ThreadMXBean threadMXBean = ManagementFactory
					.newPlatformMXBeanProxy(mBeanServerConnection,
							ManagementFactory.THREAD_MXBEAN_NAME,
							ThreadMXBean.class);
			System.out
					.println("ThreadCount = " + threadMXBean.getThreadCount());
			System.out.println("DaemonThreadCount = "
					+ threadMXBean.getDaemonThreadCount());
			System.out.println("PeakThreadCount = "
					+ threadMXBean.getPeakThreadCount());
			System.out.println("CurrentThreadCpuTime = "
					+ threadMXBean.getCurrentThreadCpuTime());
			System.out.println("CurrentThreadUserTime = "
					+ threadMXBean.getCurrentThreadUserTime());

			System.out.println("\nClassLoading");
			ClassLoadingMXBean classLoadingMXBean = ManagementFactory
					.newPlatformMXBeanProxy(mBeanServerConnection,
							ManagementFactory.CLASS_LOADING_MXBEAN_NAME,
							ClassLoadingMXBean.class);
			// 當前載入到Java虛擬機器中類的數量
			System.out.println("LoadedClassCount = "
					+ classLoadingMXBean.getLoadedClassCount());
			// Java 虛擬機器開始執行到目前已經載入的類的總數。
			System.out.println("TotalLoadedClassCount = "
					+ classLoadingMXBean.getTotalLoadedClassCount());
			// Java 虛擬機器開始執行到目前已經解除安裝的類的總數。
			System.out.println("UnloadedClassCount = "
					+ classLoadingMXBean.getUnloadedClassCount());

			System.out.println("\nCpu");
			OperatingSystemMXBean operatingSystemMXBean = ManagementFactory
					.newPlatformMXBeanProxy(mBeanServerConnection,
							ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,
							OperatingSystemMXBean.class);
			System.out.println("AvailableProcessors = "
					+ operatingSystemMXBean.getAvailableProcessors());
			double ratio = 0.0;
			long start = System.currentTimeMillis();
			long startC;
			try {
				startC = (long) mBeanServerConnection
						.getAttribute(operatingSystemMXBean.getObjectName(),
								"ProcessCpuTime");
				try {
					TimeUnit.SECONDS.sleep(5);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				long end = System.currentTimeMillis();
				long endC = (long) mBeanServerConnection
						.getAttribute(operatingSystemMXBean.getObjectName(),
								"ProcessCpuTime");

				int availableProcessors = operatingSystemMXBean
						.getAvailableProcessors();
				ratio = (endC - startC) / 1000000.0 / (end - start)
						/ availableProcessors;

			} catch (AttributeNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (InstanceNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (MBeanException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (ReflectionException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

			System.out.println("CUP使用率" + round(ratio * 100) + "%");

		} catch (MalformedURLException e) {
			e.printStackTrace();
			System.out.println("非法的ServiceURL");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (jmxConnector != null) {
					jmxConnector.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	private static String convertKB(long src) {

		if (src <= 0L) {
			return "0KB";
		}
		double conversrc = src / 1024 / 1024;

		return round(conversrc) + "MB";
	}

	private static float round(double src) {
		return (float) (Math.round(src * 100)) / 100;
	}
}

巢狀在JavaEE中的效果如下:

拿了張工作圖,不會侵權吧。。。