spring集成javamelody怎么用连接池监控sql实例

2025-05-21 08:55:07
推荐回答(2个)
回答(1):

前面写过对于webapp,用javamelody来监控、分析性能是挺方便的;那要对普通的java应用进行监控,只需要在应用上启动一个嵌入式web容器就可以了。

javamelody里面的war包就用了winstone 作为Servlet容器,可以直接启动;本文是以Jetty为例,在应用中嵌入一个jetty:

import java.util.EventListener;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.handler.ContextHandlerCollection;
import org.mortbay.jetty.handler.ResourceHandler;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.DefaultServlet;
import org.mortbay.jetty.servlet.FilterHolder;
import org.mortbay.thread.QueuedThreadPool;
import org.springframework.web.context.ContextLoaderListener;


/**
* 启动一个jetty容器,结合javamelody用于监控应用性能
* @author langke
* 2012-12-21
*/
public class JavaMelodyMonitorServer {
   private ESLogger log = Loggers.getLogger(JavaMelodyMonitorServer.class);
   Server webServer;
   /**
    *
    * @param serverName 应用名称
    * @param host    绑定的IP地址
    * @param serverPort    应用端口,jetty启动的端口默认会在此基础上加1000,如果配置文件有配置jetty.listen.port则配置优先
    */
   public JavaMelodyMonitorServer(String serverName,String host,int serverPort) {
       init(serverName, host, serverPort);
       start();
       final JavaMelodyMonitorServer server = this;
       Runtime.getRuntime().addShutdownHook(new Thread() {
           @Override
           public void run() {
               try {
                   log.info("shutdown mointorServer:{}", server);
                   server.stop();
               } catch (Exception e) {
                   log.error("run main stop error!", e);
               }
           }

       });
   }
   
   private void init(String serverName,String host,int serverPort){
       int defaultValue = serverPort+1000;
       int port = Config.get().getInt("jetty.listen.port", defaultValue);
       Connector connector = new SocketConnector();
       webServer = new Server();
       QueuedThreadPool pool = new QueuedThreadPool();
       pool.setMinThreads(Config.get().getInt("jetty.pool.MinThread", 3));
       pool.setMaxThreads(Config.get().getInt("jetty.pool.MaxThread", 32));
       String server = host;
       pool.setName(serverName+"-monitor");
       pool.setDaemon(true);
       webServer.setThreadPool(pool);
       connector = new SocketConnector();

       connector.setPort(port);
       connector.setHost(server);
       connector.setMaxIdleTime(60000); // 1 min
       webServer.addConnector(connector);
       
       ContextHandlerCollection col = new ContextHandlerCollection();
       Context context = new Context(col, "/", Context.SESSIONS);
       ResourceHandler resourceHandler = new ResourceHandler();
       webServer.setHandlers(new Handler[] {col,resourceHandler });
       webServer.addHandler(context);
         // Set Java Melody storage Directory
       System.setProperty("javamelody.storage-directory", "javamelody-"+pool.getName());
       
       //add filter
       Filter monitoringFilter = new net.bull.javamelody.MonitoringFilter();
       context.addFilter(new FilterHolder(monitoringFilter), "/monitoring", Handler.REQUEST);

       Map initParams = new HashMap();
       initParams.put("contextConfigLocation", "classpath:net/bull/javamelody/monitoring-spring.xml");
       context.setInitParams(initParams);
       
       //add listener
       EventListener listener = new ContextLoaderListener();
       context.addEventListener(listener);
       
       context.addServlet(DefaultServlet.class, "/*");
       
   }

   private void start(){
       try{
           webServer.join();
           webServer.start();
       }catch (Exception e){
           log.error("Error starting httpserver", e);
       }
   }

   private void stop(){
       try{
           webServer.stop();
           webServer.destroy();
       }catch (Exception e){
           log.error("Error stop httpserver", e);
       }

   }
}

这个jetty加了shutdown hook,应用关闭的时候会自己关闭容器。

需要的jar依赖名如下:

servlet-api-3.0.jar
org.springframework.web-3.1.0.RELEASE.jar
jrobin-1.5.9.1.jar
jetty-util-6.1.26.jar
jetty-6.1.26.jar
javamelody.jar
com.springsource.net.sf.cglib-2.2.0.jar

如果使用spring框架,监控配置就比较简单,可以对某个包所有类进行监控:


         
                 
                         
                 

         

   
       

监控数据源:

   
   

   
   
       
   

回答(2):

需要在web.xml中实现一个监听,这个监听回使web应用在读取web.xml时,加载指定的spring文件。


org.springframework.web.context.ContextLoaderListener



  然后我们通过设置参数,设置启动的spring文件

contextConfigLocation

classpath:net/bull/javamelody/monitoring-spring.xml
classpath:context/services.xml
classpath:context/data-access-layer.xml
/WEB-INF/applicationContext.xml



  注意monitoring-spring.xml与applicaitonContext.xml的位置,我好多次使用这种方式都没有成功,貌似就是这个位置的顺序颠倒了。是否是这个原因,还有待验证(明天测试,现在没有环境)。
  整个web.xml的配置文件,参考下面:




contextConfigLocation


classpath:net/bull/javamelody/monitoring-spring.xml
classpath:bean.xml




struts
org.apache.struts2.dispatcher.FilterDispatcher


struts.action.extension
action



struts
/*



monitoring
net.bull.javamelody.MonitoringFilter


log
true



monitoring
/*


net.bull.javamelody.SessionListener




org.springframework.web.context.ContextLoaderListener



index.jsp