• javamelody对Java Application进行监控


    前面写过对于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<String,String> initParams = new HashMap<String,String>();
            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,应用关闭的时候会自己关闭容器。

    然后在你的Application里实例化这个类就行了;

    需要的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框架,监控配置就比较简单,可以对某个包所有类进行监控:

    复制代码
        <bean id="facadeMonitoringAdvisor" class="net.bull.javamelody.MonitoringSpringAdvisor">
              <property name="pointcut">
                      <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
                              <property name="pattern" value="org.langke.core.service.*" />
                      </bean>
              </property>
        </bean>        
        
    复制代码

    监控数据源:

        <bean id="springDataSourceBeanPostProcessor" class="net.bull.javamelody.SpringDataSourceBeanPostProcessor">
         </bean>
        
         <bean id="wrappedDataSource" class="net.bull.javamelody.SpringDataSourceFactoryBean">
            <property name="targetName" value="dataSource" />
        </bean>

    还有一种方式:注解

    只需添加注解@net.bull.javamelody.MonitoredWithGuice在你的实现类或者你要监控的方法:使用net.bull.javamelody.MonitoringProxy类代理

    详见:http://code.google.com/p/javamelody/wiki/UserGuide#10._Business_facades_(if_Guice)

    如果不用Spring也不用Guice还有一种简单的方法实现监控

    详见:http://code.google.com/p/javamelody/wiki/UserGuideAdvanced#Business_facades_(without_EJB3_and_without_Spring_and_without_Gu

     

    具体的集成方式,稍后会在我的github发布出来

     https://github.com/langke93/rest-nettyserver

  • 相关阅读:
    AJax封装避免页面重复代码
    word 2010 建立多级结构和目录
    (转)C# 选择正确的集合
    IIS7如何部署asp.net网站 (asp.net mvc 5 , asp.net 4.5 , asp.net 4.0 都可以 )
    (转)程序集清单定义与程序集引用不匹配- 分析及解决
    CentOS 6.5 安装 MySQL5.6 并用Navicat for MySQL 连接
    用EF访问Centos下的MySQL
    SQLServer中的页如何影响数据库性能 (转)
    .NET Framework各版本比较
    EntityFramework简介
  • 原文地址:https://www.cnblogs.com/muhy/p/10027204.html
Copyright © 2020-2023  润新知