`
leadyu
  • 浏览: 51434 次
  • 性别: Icon_minigender_1
  • 来自: 广州,福州
文章分类
社区版块
存档分类
最新评论

Jwebap项目(四)——性能监控工具Jwebap: 0.5.8版本发布

阅读更多
一直想写一篇关于Jwebap(jwebap.sourceforge.net)项目的介绍文章,鉴于0.5.8版本的发布,我整理了下发表出来,希望大家感兴趣。

引用
背景
最初,在06年底由于要帮助几个大型项目进行性能上的优化,有了开发一个专用于profiling组件的想法,于是有了Jwebap,慢慢的到了07年6月份开始有了最初的方案,在11月终于在sourceforge上发布了第一个版本。

Jwebap能带来什么?
Jwebap是一个用于J2EE工程(EJB以及WebModule系统)进行性能监控的组件,它有几个特点:

1)基于ASM实现类的静态增强,可以无缝的部署于J2EE系统,对系统的开销几乎可以忽略

2)部署和使用非常的简单,整个Jwebap的部署只需要部署jwebap_core_**.jar以及需要使用的各种plugin_**.jar,然后配置jwebap.xml和web.xml就可以完成所有的部署,比起绝大多数的profiling容易的多。

同时Jwebap提供Web Console进行整个Jwebap的管理和数据展现。在API层提供一套默认的视图框架供plugin开发者使用,可以只用Jar包就开发出相当漂亮的Web界面。

3)Jwebap的开发分为两个部分Jwebap-core部分,Jwebap-plugin部分。core部分基于jdk14提供了类静态增强,轨迹生命管理,Plugin管理,视图框架等等,在这个基础上开发plugin。我觉得,好的profiling应该能够根据不同的人群按需使用,同时在功能不断复杂和强大的过程中仍然能够保证较轻的架子。

目前,0.5.8提供了基于jdk14的三个plugin:method监控,jdbc监控,http监控。这些可以算是基于plugin架构开发的示例。以后会开发更多的plugin,比如memory_monitor_plugin。甚至可以基于一些专属平台开发功能更强的插件。当然,Jwebap也可以不仅仅停留在profiling,日后,可以基于测试人员和质量保证,开发人员等方面开发适用的plugin,做到按需分配。


Jwebap的部署

Jwebap的部署相当简单,0.5.8版本提供了一个把plugin和core打在一起的包:jwebap_0.5.8_all.jar。然后对于jwebap.xml和web.xml的配置可以参看doc目录下的User-Guide。目前,0.5.8版本能够做到的功能有:

Jdbc监控:可以监控J2EE系统的所有Jdbc调用,包括Jndi数据源,可以过滤SQL时间,由哪些程序调用,哪些连接泄露。

Method监控:可以通过配置Method Plugin的'detect-class'参数,配置多个想要监控的包或类,Jwebap Console就可以跟踪这些类的方法执行,进行时间过滤,可以统计开销,和方法的调用堆栈,方法打开了多少Jdbc连接等等。

Http监控:可以监控http请求,进行时间过滤,可以进行请求的开销统计,请求打开了多少Jdbc连接等等。


贴几张示例图,有兴趣的朋友可以下载试用(jwebap.sourceforge.net),欢迎在这里进行交流:
  • 描述: Jdbc Traces 1
  • 大小: 148.2 KB
  • 描述: Jdbc Traces 2
  • 大小: 118.4 KB
  • 描述: Method Traces
  • 大小: 98.6 KB
分享到:
评论
112 楼 bluelover 2009-01-05  
不错的东西
111 楼 leasass 2008-11-06  
记号一下,有空要试试
110 楼 xpfly 2008-11-06  
启动时出现如下错误:我用的是weblogic8
<2008-11-6 15时21分50秒 GMT+08:00> <Notice> <WebLogicServer> <BEA-000327> <Starting WebLogic Admin Server "myserver" for domain "dmctais">
2008-11-06 15:22:28,600 INFO HttpComponent:44 [main] - httpcomponent startup.
2008-11-06 15:22:28,636 INFO MethodComponent:52 [main] - methodcomponent startup.
org.jwebap.toolkit.bytecode.InjectException: oracle.jdbc.driver.OracleDriver注入失败.
        at org.jwebap.toolkit.bytecode.asm.ASMInjectorStrategy.injectInternal(ASMInjectorStrategy.java:149)
        at org.jwebap.toolkit.bytecode.asm.ASMInjectorStrategy.inject(ASMInjectorStrategy.java:117)
        at org.jwebap.toolkit.bytecode.ClassEnhancer.createClass(ClassEnhancer.java:107)
        at org.jwebap.toolkit.bytecode.ClassEnhancer.createClass(ClassEnhancer.java:95)
        at org.jwebap.plugin.jdbc.JdbcComponent.injectJdbcDriver(JdbcComponent.java:133)
        at org.jwebap.plugin.jdbc.JdbcComponent.startup(JdbcComponent.java:62)
        at org.jwebap.core.context.RuntimeContext.registerComponent(RuntimeContext.java:51)
        at org.jwebap.core.Startup.startup(Startup.java:75)
        at org.jwebap.core.JwebapListener.contextInitialized(JwebapListener.java:33)
        at weblogic.servlet.internal.WebAppServletContext$FireContextListenerAction.run(WebAppServletContext.java:6781)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
        at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
        at weblogic.servlet.internal.WebAppServletContext.notifyCreated(WebAppServletContext.java:1681)
        at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext.java:3255)
        at weblogic.servlet.internal.WebAppServletContext.setStarted(WebAppServletContext.java:5949)
        at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:862)
        at weblogic.j2ee.J2EEApplicationContainer.start(J2EEApplicationContainer.java:2127)
        at weblogic.j2ee.J2EEApplicationContainer.activate(J2EEApplicationContainer.java:2168)
        at weblogic.j2ee.J2EEApplicationContainer.activate(J2EEApplicationContainer.java:2115)
        at weblogic.management.deploy.slave.SlaveDeployer$Application.setActivation(SlaveDeployer.java:3082)
        at weblogic.management.deploy.slave.SlaveDeployer.setActivationStateForAllApplications(SlaveDeployer.java:1751)
        at weblogic.management.deploy.slave.SlaveDeployer.resume(SlaveDeployer.java:359)
        at weblogic.management.deploy.DeploymentManagerServerLifeCycleImpl.resume(DeploymentManagerServerLifeCycleImpl.java:229)
        at weblogic.t3.srvr.SubsystemManager.resume(SubsystemManager.java:131)
        at weblogic.t3.srvr.T3Srvr.resume(T3Srvr.java:966)
        at weblogic.t3.srvr.T3Srvr.run(T3Srvr.java:361)
        at weblogic.Server.main(Server.java:32)
Caused by: org.jwebap.toolkit.bytecode.asm.DefineBytecodeException: oracle/jdbc/driver/OracleDriver注入错误:JVMCL048:redefine of class oracle/jdbc/driver/OracleDriver (&name=1134CECB0). old_cb=70000000017A3A0, new_cb=700000000433588, (&old_name=1134CECB0) old_name=oracle/jdbc/driver/OracleDriver
        at org.jwebap.toolkit.bytecode.asm.ASMInjectorStrategy.defineClass(ASMInjectorStrategy.java:305)
        at org.jwebap.toolkit.bytecode.asm.ASMInjectorStrategy.defineClass(ASMInjectorStrategy.java:215)
        at org.jwebap.toolkit.bytecode.asm.ASMInjectorStrategy.defineClass(ASMInjectorStrategy.java:201)
        at org.jwebap.toolkit.bytecode.asm.ASMInjectorStrategy.defineClass(ASMInjectorStrategy.java:201)
        at org.jwebap.toolkit.bytecode.asm.ASMInjectorStrategy.defineClass(ASMInjectorStrategy.java:201)
        at org.jwebap.toolkit.bytecode.asm.ASMInjectorStrategy.defineClass(ASMInjectorStrategy.java:201)
        at org.jwebap.toolkit.bytecode.asm.ASMInjectorStrategy.injectInternal(ASMInjectorStrategy.java:142)
        ... 26 more
Caused by: java.lang.LinkageError: JVMCL048:redefine of class oracle/jdbc/driver/OracleDriver (&name=1134CECB0). old_cb=70000000017A3A0, new_cb=700000000433588, (&old_name=1134CECB0) old_name=oracle/jdbc/driver/OracleDriver
        at java.lang.ClassLoader.defineClass0(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java(Compiled Code))
        at java.lang.ClassLoader.defineClass(ClassLoader.java:708)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java(Compiled Code))
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java(Compiled Code))
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java(Compiled Code))
        at java.lang.reflect.Method.invoke(Method.java(Compiled Code))
        at org.jwebap.toolkit.bytecode.asm.ASMInjectorStrategy.defineClass(ASMInjectorStrategy.java:302)
        ... 32 more
2008-11-06 15:22:29,143 WARN JdbcComponent:138 [main] - 对数据库驱动:oracle.jdbc.driver.OracleDriver的监听部署失败,不过这并不影响系统的运行。
109 楼 sharkdika 2008-08-12  
问个菜鸟问题
什么URL可以看到那个监控界面?
108 楼 mrjamesli 2008-06-04  
不好意思,已解决了,是驱动的jar包中有数字签名,删除数字签名就可以了
107 楼 xianyunheying 2008-06-04  
leadyu 写道
leadyu 写道
zbird 写道
我出这个问题
Caused by: java.lang.ClassCastException: org.jwebap.plugin.jdbc.TraceDetectConnection cannot be cast to oracle.jdbc.driver.OracleConnection
at oracle.jdbc.driver.OracleDriver.connect_$proxy(OracleDriver.java:345)
... 54 more


这个问题,我会尽快检查,可能是由于oracle驱动,内部有私有方法也返回Connection,而connect()方法内部去cast这个Connection(已经被jwebap代理过了),所以cast失败。


我刚才看了oracle驱动的源码,确实如我猜测的那样,这个bug,我明天发布jwebap_0.5.8_all_4.zip,请关注。

我写了个程序,也是这个问题。你能告诉我这个问题怎么解决吗?
106 楼 mrjamesli 2008-06-04  
我的系统是tomcat6,数据库是sqlserver2005,启动时显示:
2008-06-04 16:08:27,890 INFO HttpComponent:44 [main] - httpcomponent startup.
2008-06-04 16:08:28,078 INFO MethodComponent:52 [main] - methodcomponent startup
.
2008-06-04 16:08:28,234 INFO JdbcComponent:87 [main] - jdbccomponent startup.
2008-06-04 16:08:28,234 INFO Startup:81 [main] - jwebap component startup.

表明jwebap已经加载。但是连接池(dbcp)初始化时显示如下错误:
Cannot load JDBC driver class 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
java.lang.SecurityException: class "com.microsoft.sqlserver.jdbc.SQLServerExcept
ion"'s signer information does not match signer information of other classes in
the same package
        at java.lang.ClassLoader.checkCerts(ClassLoader.java:775)
        at java.lang.ClassLoader.preDefineClass(ClassLoader.java:487)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:614)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
        at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1819)
        at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:872)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1327)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1206)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:164)
        at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:760)
        at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:540)
        。。。。。。。。。。。。。
这是什么原因啊
105 楼 jxb8901 2008-04-11  
不好意思,已解决了,是我自己配置的问题。
104 楼 zbird 2008-03-28  
汇总统计里面最好也能加个清零的功能。
如果系统运行了很久,可能在后期边慢了。
但前面的基数比较大,看上去平均值变化不到。
如果加个清理的功能就可以了解相对实时的统计数据了。
103 楼 zhuyx808 2008-03-27  
最好是吧这些数据写成日志或者写进数据库,另外在增加一个写不写进的开关,因为这个数据都是固定的,建数据库表也比较固定了
102 楼 dream实现 2008-03-26  
我也想汉化一下,感觉这东西确实不错,不过修改了一下那个模板,不论怎么设置编码,修改后都是乱码,那个是common template的模板,请赐教一下,该如何设置
101 楼 zhuyx808 2008-03-26  
乱码问题怎麽解决?
100 楼 ajoo 2008-03-26  
用cglib的FastMethod,会快不少。另外,如果不需要做around interceptor。用cglib的Dispatcher接口,效率几乎可以赶上直接的虚函数调用。
99 楼 leadyu 2008-03-25  
myreligion 写道

我倒是希望能找到一个可以对执行的sql语句进行分类汇总的软件,可以统计好比有多少sql执行了多少次,每个sql语句的平均时间是多少。类似于oracle的查询分析工具。一直在用mysql,缺少这类东西,不知道Jwebap可否满足?


jwebap以后所有的监控功能都是plugin,现在的三个plugin还很基础,如果你有plugin的想法,欢迎交流^_^
98 楼 leadyu 2008-03-25  
meikefu 写道
看到这个接口MethodInjectHandler.invoke传入的是java.lang.reflect.Method,源码中的2个实现类JdbcDriverInjectHandle,TraceMethodHandle,前者是after,后者是before.
看了看源码jwebapp,没有注入原方法,而是proxy原方法,如果以一个方法为元单位,除了before和after还有什么形式的注入?
数据库连接应该是一个系统的核心,如果在关键模块大量运用反射会导致性能下降


会有更复杂的需求的,比如JdbcDriverInjectHandle,包装返回对象:

Object o;
		try {
			o = methodProxy.invoke(target, args);
		} catch (InvocationTargetException e) {
			// 抛出原有异常
			throw e.getCause();
		} finally {

		}
		if (!Modifier.isPrivate(method.getModifiers())
				&& Connection.class.equals(method.getReturnType())
				&& o instanceof Connection
				&& !(o instanceof TraceDetectConnection)) {
			return new TraceDetectConnection(_container, (Connection) o,
					_listeners);
		} else if (!Modifier.isPrivate(method.getModifiers())
				&& DataSource.class.equals(method.getReturnType())
				&& o instanceof DataSource
				&& !(o instanceof TraceDetectDataSource)) {
			return new TraceDetectDataSource(_container, (DataSource) o,
					_listeners);
		} else {
			return o;
		}


以后,会有更复杂的场景,至于反射带来了多大开销,起码从目前,我在几个电信省级生产系统的应用来看,没有感觉,当然以后,我觉得还需要细致的性能测试,我希望jwebap能够更多的应用于生产系统,这样才能真正解决问题(在几个存在性能问题的电信省级生产系统的应用中已经起到了很大的作用)

97 楼 meikefu 2008-03-25  
引用
生产环境应当没谁会去挂一个性能监视平台吧。
我觉得性能监视平台的效率只要不低到影响测试结果就不用做这么多考虑。

不在生产环境上面监控在那里监控?刚才测试一下
public Integer step(Integer value)
	{
		return new Integer(value.intValue()*value.intValue());
	}
	
	public int callReferenceArgs(int loops) {
	    TimingClass timing = new TimingClass();
	    Integer value = new Integer(1234);
	    for (int index = 0; index < loops; index++) {
	        value = timing.step(value);
	    }
	    return value.intValue();
	}
	public int callReflectArgs(int loops) {
	    TimingClass timing = new TimingClass();
	    try {
	        Method method = TimingClass.class.getMethod
	            ("step", new Class [] { Integer.class });
	        Object[] args = new Object[1];
	        Object value = new Integer(1234);
	        for (int index = 0; index < loops; index++) {
	            args[0] = value;
	            value = method.invoke(timing, args);
	        }
	        return ((Integer)value).intValue();
	    } catch (Exception e) {
	        e.printStackTrace();
	    	return 0;
	    }
	}
	
	public static void main(String[] args) throws Exception
	{
		TimingClass tc = new TimingClass();
		int loop = 1000000;
		
		long a = System.currentTimeMillis();
		tc.callReferenceArgs(loop);
		System.out.println("引用调用:"+(System.currentTimeMillis() -a));
		
		long b = System.currentTimeMillis();
		tc.callReflectArgs(loop);
		System.out.println("反射调用:"+(System.currentTimeMillis() -b));
	}

在jre1.4下引用调用:31反射调用:219,差距有7倍左右.但是单位是毫秒,如果并发量不大应该整个系统的瓶颈应该不会在这里,只是为了探讨一下性能问题.


能否考虑接入jmx的mbean监控webserver的连接池,线程池,jms,jta,etc期待MemoryComponent,希望jwebapp更好更强
96 楼 myreligion 2008-03-25  

我倒是希望能找到一个可以对执行的sql语句进行分类汇总的软件,可以统计好比有多少sql执行了多少次,每个sql语句的平均时间是多少。类似于oracle的查询分析工具。一直在用mysql,缺少这类东西,不知道Jwebap可否满足?
95 楼 zbird 2008-03-25  
生产环境应当没谁会去挂一个性能监视平台吧。
我觉得性能监视平台的效率只要不低到影响测试结果就不用做这么多考虑。
94 楼 meikefu 2008-03-25  
看到这个接口MethodInjectHandler.invoke传入的是java.lang.reflect.Method,源码中的2个实现类JdbcDriverInjectHandle,TraceMethodHandle,前者是after,后者是before.
看了看源码jwebapp,没有注入原方法,而是proxy原方法,如果以一个方法为元单位,除了before和after还有什么形式的注入?
数据库连接应该是一个系统的核心,如果在关键模块大量运用反射会导致性能下降
93 楼 leadyu 2008-03-25  
meikefu 写道
jwebapp注入的方法都使用反射Method.invoke来调用源方法,开销比较大,如果换成直接调用是否能降低开销


没有那么简单,对于原方法的调用是可以直接调用而且实现起来简单的多,但是这样只能实现,before和after的注入,注入的功能大大减弱。

所以,出于这点的考虑,jwebap简单的实现了invokeHandle的注入方式(还有需要改进的地方,比如多handle注入),可以用的很灵活,有兴趣的话可以参考JdbcComponent插件里面的JdbcInvokeHandle的运用方法。

相关推荐

    GPU-Z.0.5.8

    GPU-Z.0.5.8显卡详细显示工具自己试试

    soljson-v0.5.8 commit.23d335f2.js

    soljson-v0.5.8 commit.23d335f2.js soljson-v0.5.8 commit.23d335f2.js

    Blueprint css框架2013年最新可视化操作工具-boks-v0.5.8

    最新版div+css可视化开发工具,boks-v0.5.8,适用于blueprint css框架的开发,拖拉拽即可导出漂亮的网页架构。

    OpenCore-0.5.8

    OpenCore是类似于Clover的UEFI的引导器,OpenCore提供了详细的日志系统,帮助黑苹果排错;其次OpenCore以更先进的方法注入第三方Kext,不破坏系统的SIP;再次,OpenCore支持读取NVRAM等一系列特性,可以让黑苹果变得...

    docker-ghost:Docker 容器中的 Ghost

    版本幽灵: 0.5.8 NodeJS: 0.12.0 Ubuntu: 14.04.01用法克隆存储库 git clone git@github.com:zaiste/docker-ghost.git构建图像 cd docker-ghost sudo docker build -t &lt;your&gt;/ghost:0.5.8 .更新幽灵替换以下行中...

    Python库 | tushare-0.5.8.zip

    python库。 资源全名:tushare-0.5.8.zip

    Android代码-MaterialLoadingProgressBar

    compile('com.lsjwzh:materialloadingprogressbar:0.5.8-RELEASE') xml: options: java api: show arrow 'CircleProgressBar' will not show arrow by default. You can enable arrow drawing like this: ...

    Python库 | pycryptopp-0.5.8.zip

    资源分类:Python库 所属语言:Python 资源全名:pycryptopp-0.5.8.zip 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    GPU-Z.0.5.8 汉化版

    GPU-Z是提供给我们的一款GPU识别工具,绿色免安装,界面直观,运行后即可显示GPU核心,以及运行频率、带宽等,如同CPU-Z一样,这也是款必备工具

    Python库 | sovereign-0.5.8.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:sovereign-0.5.8.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    colonyNetwork:殖民地网络智能合约

    殖民地网络 定义的运行殖民地网络的合同 错误赏金计划 ... $ docker pull ethereum/solc:0.5.8 安装 在您选择的工作目录中,克隆最新版本的ColonyNetwork存储库: $ git clone https://github.com/JoinColo

    Python库 | tribology-0.5.8.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:tribology-0.5.8.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Python库 | reprobench-0.5.8.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:reprobench-0.5.8.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Python库 | pyunicore-0.5.8.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:pyunicore-0.5.8.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Python库 | OLCTools-0.5.8.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:OLCTools-0.5.8.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Python库 | dandan-0.5.8.tar.gz

    python库。资源全名:dandan-0.5.8.tar.gz

    Python库 | BentoML-0.5.8.tar.gz

    python库。资源全名:BentoML-0.5.8.tar.gz

    Python库 | JPSLUtils-0.5.8.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:JPSLUtils-0.5.8.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Python库 | braga-0.5.8.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:braga-0.5.8.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Python库 | anndata-0.5.8.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:anndata-0.5.8.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

Global site tag (gtag.js) - Google Analytics