前面写过对于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() {@Overridepublic 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 minwebServer.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 DirectorySystem.setProperty("javamelody.storage-directory", "javamelody-"+pool.getName());//add filterFilter 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 listenerEventListener 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