From cc24af9812ab0694df80fc66ed9e596f37c62f35 Mon Sep 17 00:00:00 2001 From: yunnysunny Date: Sat, 23 Mar 2013 17:11:21 +0800 Subject: [PATCH] add the function of getting duird's monitor data form remote server via jmx. --- .../alibaba/druid/stat/DruidStatService.java | 2 +- .../druid/support/http/StatViewServlet.java | 134 +++++++++++++++++- 2 files changed, 134 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/alibaba/druid/stat/DruidStatService.java b/src/main/java/com/alibaba/druid/stat/DruidStatService.java index 1b510e0804..4494694218 100644 --- a/src/main/java/com/alibaba/druid/stat/DruidStatService.java +++ b/src/main/java/com/alibaba/druid/stat/DruidStatService.java @@ -299,7 +299,7 @@ public final class DruidStatService implements DruidStatServiceMBean { return returnJSONResult(RESULT_CODE_SUCCESS, result); } - private String returnJSONResult(int resultCode, Object content) { + public static String returnJSONResult(int resultCode, Object content) { Map dataMap = new LinkedHashMap(); dataMap.put("ResultCode", resultCode); dataMap.put("Content", content); diff --git a/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java b/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java index 2342ccb306..b3d4400abc 100644 --- a/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java +++ b/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java @@ -16,9 +16,17 @@ package com.alibaba.druid.support.http; import java.io.IOException; +import java.net.MalformedURLException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -50,6 +58,10 @@ public class StatViewServlet extends HttpServlet { public static final String PARAM_NAME_USERNAME = "loginUsername"; public static final String PARAM_NAME_PASSWORD = "loginPassword"; + + public static final String PARAM_NAME_JMX_URL = "jmxUrl"; + public static final String PARAM_NAME_JMX_USERNAME = "jmxUsername"; + public static final String PARAM_NAME_JMX_PASSWORD = "jmxPassword"; public static final String SESSION_USER_KEY = "druid-user"; @@ -65,6 +77,14 @@ public class StatViewServlet extends HttpServlet { private String username = null; private String password = null; + + /** web.xml中配置的jmx的连接地址 */ + private String jmxUrl = null; + /** web.xml中配置的jmx的用户名 */ + private String jmxUsername = null; + /** web.xml中配置的jmx的密码 */ + private String jmxPassword = null; + private MBeanServerConnection conn = null; public void init() throws ServletException { initAuthEnv(); @@ -127,6 +147,118 @@ public class StatViewServlet extends HttpServlet { String msg = "initParameter config error, deny : " + getInitParameter(PARAM_NAME_DENY); LOG.error(msg, e); } + + //获取jmx的连接配置信息 + String param = readInitParam(PARAM_NAME_JMX_URL); + if (param != null) { + jmxUrl = param; + jmxUsername = readInitParam(PARAM_NAME_JMX_USERNAME); + jmxPassword = readInitParam(PARAM_NAME_JMX_PASSWORD); + try { + initJmxConn(); + } catch (IOException e) { + LOG.error("init jmx connection error", e); + } + } + + } + + /** + * 读取servlet中的配置参数. + * + * @param key 配置参数名 + * @return 配置参数值,如果不存在当前配置参数,或者为配置参数长度为0,将返回null + */ + private String readInitParam(String key) { + String value = null; + try { + String param = getInitParameter(key); + if (param != null) { + param = param.trim(); + if (param.length() > 0) { + value = param; + } + } + } catch (Exception e) { + String msg = "initParameter config ["+ key +"] error"; + LOG.warn(msg, e); + } + return value; + } + + /** + * 初始化jmx连接 + * @throws IOException + * */ + private void initJmxConn() throws IOException { + if (jmxUrl != null) { + JMXServiceURL url = new JMXServiceURL(jmxUrl); + Map env = null; + if (jmxUsername != null) { + env = new HashMap(); + String[] credentials = new String[]{jmxUsername,jmxPassword}; + env.put(JMXConnector.CREDENTIALS, credentials); + } + JMXConnector jmxc = JMXConnectorFactory.connect(url, env); + conn = jmxc.getMBeanServerConnection(); + } + } + + /** + * 根据指定的url来获取jmx服务返回的内容. + * + * @param connetion jmx连接 + * @param url url内容 + * @return the jmx返回的内容 + * @throws Exception the exception + */ + private String getJmxResult(MBeanServerConnection connetion,String url) + throws Exception { + ObjectName name = new ObjectName(DruidStatService.MBEAN_NAME); + + String result = (String) conn.invoke(name, "service", + new String[] { url }, new String[] { String.class.getName() }); + return result; + } + + /** + * 程序首先判断是否存在jmx连接地址,如果不存在,则直接调用本地的duird服务; + * 如果存在,则调用远程jmx服务。在进行jmx通信,首先判断一下jmx连接是否已经建立成功,如果已经 + * 建立成功,则直接进行通信,如果之前没有成功建立,则会尝试重新建立一遍。. + * + * @param url 要连接的服务地址 + * @return 调用服务后返回的json字符串 + */ + private String genServiceResponse(String url) { + String resp = null; + if (jmxUrl == null) { + resp = statService.service(url); + } else { + if (conn == null) {//连接在初始化时创建失败 + try {//尝试重新连接 + initJmxConn(); + } catch (IOException e) { + LOG.error("init jmx connection error", e); + resp = DruidStatService.returnJSONResult(DruidStatService.RESULT_CODE_ERROR, "init jmx connection error"+e.getMessage()); + } + if (conn != null) {//连接成功 + try { + resp = getJmxResult(conn,url); + } catch (Exception e) { + LOG.error("get jmx data error", e); + resp = DruidStatService.returnJSONResult(DruidStatService.RESULT_CODE_ERROR, "get data error:"+e.getMessage()); + } + } + } else {//连接成功 + try { + resp = getJmxResult(conn,url); + } catch (Exception e) { + LOG.error("get jmx data error", e); + resp = DruidStatService.returnJSONResult(DruidStatService.RESULT_CODE_ERROR, "get data error"+e.getMessage()); + } + } + } + return resp; } private void initAuthEnv() { @@ -242,7 +374,7 @@ public class StatViewServlet extends HttpServlet { if (request.getQueryString() != null && request.getQueryString().length() > 0) { fullUrl += "?" + request.getQueryString(); } - response.getWriter().print(statService.service(fullUrl)); + response.getWriter().print(genServiceResponse(fullUrl)); return; }