论坛首页 Java企业应用论坛

用jamon来监控你的sql执行效率

浏览 19407 次
该帖已经被评为良好帖
作者 正文
   发表时间:2008-02-25  
/**

*作者:张荣华

*日期:2008-2-25

**/

之前有一篇文章讲到如何使用jamon来监控请求以及方法得调用(原文地址见:[url]http://www.iteye.com/post/354575 [/url]),本文属于其姊妹篇,使用jamon监控系统的sql调用及其调用效率。

需求:
1我们知道在使用hibernate得时候,我们可以打开show sql选项,可以直接查看sql语句调用的情况,那么当我们使用其他持久技术的时候我们也需要这个功能怎么办呢,没有关系,jamon能够帮我们做到。

2 很多时候,不同的程序员会写出不同的性能的sql,有时候可能会不小心或者因为不知道而写出性能很差的sql,我自己曾经就发生过这种事情,在500w条数据的表里使用了一个limit来分页,到后面,执行一条sql都需要几分钟,诸如此类的时候可能大家都有碰到过,如果能有监控sql性能的工具嵌在应用里该多好,当然有jamon就可以帮我们做到。

对于jamon来说,每一个query的执行之后的统计结果都会被保存下来,这些概要统计都以MonProxy-SQL开头。这些统计中包括查询执行的时间,有比如平均时间,执行总时间,最小执行时间,最大执行时间,这些东西难道不是我们正想要的吗。

那么让我们开始吧,我们知道,这些query执行的统计应该是在connection中被统计的,也就是说我们要代理一般的connection,而connection又是由datasource产生的,所以我们可以代理datasource,说干就干。

一个datasource接口中关于connection的方法只有两个:
/**
   * <p>Attempts to establish a connection with the data source that
   * this <code>DataSource</code> object represents.
   *
   * @return  a connection to the data source
   * @exception SQLException if a database access error occurs
   */
  Connection getConnection() throws SQLException;
      
  /**
   * <p>Attempts to establish a connection with the data source that
   * this <code>DataSource</code> object represents.
   *
   * @param username the database user on whose behalf the connection is 
   *  being made
   * @param password the user's password
   * @return  a connection to the data source
   * @exception SQLException if a database access error occurs
   * @since 1.4
   */
  Connection getConnection(String username, String password) 
    throws SQLException;

也就是说我们只要override这两个方法即可。
根据这个思路我写了以下代码:
/**
 * @author ahuaxuan(aaron zhang)
 * @since 2008-2-25
 * @version $Id$
 */
public class MonitorDataSource implements DataSource {
	public DataSource realDataSource;

	public void setRealDataSource(DataSource realDataSource) {
		this.realDataSource = realDataSource;
	}

	public DataSource getRealDataSource() {
		return realDataSource;
	}
	public Connection getConnection() throws SQLException {
//表示由jamon来代理realDataSource返回的Connection
		return MonProxyFactory.monitor(realDataSource.getConnection());
	}

	public Connection getConnection(String username, String password)
			throws SQLException {
//表示由jamon来代理realDataSource返回的Connection

		return MonProxyFactory.monitor(realDataSource.getConnection(username,
				password));
	}
}

显然这个一个代理模式。接下来就是生成这个代理类,我是在spring中注册了这么一个类:
<bean id="writeMonitorDataSource" class="org.ahuaxuan.MonitorDataSource" destroy-method="close">
		<property name="realDataSource" ref="writeDataSource"/>
	</bean>


writeMonitorDataSource 所依赖的writeDataSource就是我们真正配置的datasource,比如:
<bean id="writeDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName">
			<value>${jdbc.driverClassName}</value>
		</property>
		<property name="url">
			<value>${jdbc.url}</value>
		</property>
		<property name="username">
			<value>${jdbc.username}</value>
		</property>
		<property name="password">
			<value>${jdbc.password}</value>
		</property>
        <property name="maxActive">
            <value>${jdbc.maxActive}</value>
        </property>
        <property name="maxIdle">
        	<value>${jdbc.maxIdle}</value>
        </property>
        <property name="maxWait">
        	<value>${jdbc.maxWait}</value>
        </property>
</bean>

好了,那么在使用datasource的时候,我们应该用哪个呢,当然是writeMonitorDataSource这个里,我们可以把它注入给jdbcTemplate,或者sessionfactory,或者其他需要用到datasource的地方。

到这里,就一切准备完毕了,我们可以看看我们sql语句的执行效率了(这个页面的地址为sql.jsp):
见图1
当然要我们的应用能够显示这个页面,我们需要把jamon的一组页面拷到我们的应用中,这一组页面包含在我提供下载的包中,最新的jamon版本是2.7。

我们可以看到id为153的那条sql语句执行了78ms,我要去看看这条sql语句是不是有点什么问题或者是否有优化的可能性。

当然,刚才说到每一条sql语句都是有统计平均时间,最大最小执行时间等等,没错,在另外一个页面jamonadmin.jsp上就包含这些内容
见图2
      

上面的图片代表hits表示执行次数,avg表示sql执行的平均时间,后面的min和max表示sql执行的最小耗时和最大耗时。从这里我们能够更直观的看到我们每条sql语句执行的情况。很有用的一个功能。

而且在上面那两个页面上,我们还可以选择把sql执行的结果导出来,可以导成xml或excel格式。

总结:使用jamon来监控我们的sql语句我觉得很有使用意义,而且使用jamon对我们的应用来说完全是松耦合的,根本不需要更改我们的业务逻辑代码,完全是可插拔的,我们也可以开发时使用jamon,部署时拔掉jamon。有了它能够使一些程序员能够更多一点的关注自己所写的sql的效率,当然如果之前开发的时候没有使用jamon也没有关系,即使上线后也可以查看一下sql语句是否有问题,比如哪些sql语句执行得比较频繁,是否存在给其做缓存得可能性等等。总之使用jamon在应用程序中来监控我们得sql语句具有很强得实用意义,

再次总结:jamon,很好,很强大。
  • 大小: 45.9 KB
  • 大小: 19.7 KB
  • jar.rar (320.2 KB)
  • 描述: 需要的jar文件
  • 下载次数: 783
   发表时间:2008-02-26  
wener 写道
好东西,支持

用它我们可以做很多东西,比如性能监控系统,一个企业中必定有很多的app,那么所有的app都可以利用它来搜集请求的数据,不管是http请求,还是jdbc,这些数据都可以搜集起来,然后再统计分析,所以jamon是一个很有用的东西,虽然原理简单,但是自己开发一个成本也比较大,直接扩展它比如方便,真的是一个很好的东西,可惜没有人认识到它的价值
0 请登录后投票
   发表时间:2008-02-26  
看起来不错。不过你是否问过DBA能够利用数据库提供的工具统计到类似的结果呢?或者说,对比后者,jamon有啥优点,有啥缺点?
0 请登录后投票
   发表时间:2008-02-26  
sorphi 写道
看起来不错。不过你是否问过DBA能够利用数据库提供的工具统计到类似的结果呢?或者说,对比后者,jamon有啥优点,有啥缺点?

这些问题我也想过
第一个问题,
数据库提供得工具来统计?

1 是两个部分要同时抓,数据库统计得是所有请求,一定程度上加大得数据库的压力,当然如果数据库压力不大的情况下这样做完全没有问题。

2 可以使用sniffer抓包来分析数据库的压力情况,但这种数据无法收集起来供我们所用。当然如果我们不需要这些数据,只是随便看看,遇到问题分析一下,使用sniffer不失为一个比较好的方案。

而对比jamon来说,jamon搜集的数据对我们来说失可以随意存储分析的,比如上面所说到的做一个负载分析系统,那么使用它来搜集数据对编程来说其实是非常方便的。
0 请登录后投票
   发表时间:2008-02-26  
用来统计一个页面到底有多少数据库请求不错。

性能方面,我所在的公司更重视SQL review,(因为有非常牛的DBA,ORACLE ACE)。
低性能sql基本都会被review这关挡掉。

而数据库压力,是在定技术方案时,就已经有底的。如果sql数据吞吐量会超标,会在这个阶段想好对策。


0 请登录后投票
   发表时间:2008-02-26  
性能监控方面,也推荐下我的项目:jwebap.sourceforge.net

它不仅仅可以监控j2ee工程(包括EJB以及WebModule)的所有的jdbc调用,包括调用的堆栈(什么程序打开的连接),还可以监控方法的调用,以及http的请求,所有的这一切,只需要部署一个jar,以及配置一个配置文件。

另外,jwebap基于plugin架构,core部分基于jdk14,所有的监控组件都是plugin,大部分的plugin基于jdk14,以后会开发一些针对专属平台的plugin, 下阶段准备开发基于jdk15的memory_monitor_plugin。

它同时提供Web Console,界面也相当美观,全部通过jar包实现。下面贴几张出来:

  • 描述: Method Traces
  • 大小: 98.6 KB
  • 描述: Jdbc Traces 2
  • 大小: 118.4 KB
  • 描述: Jdbc Traces 1
  • 大小: 148.2 KB
0 请登录后投票
   发表时间:2008-02-26  
楼上的,界面是用ext做的吗?
1 请登录后投票
   发表时间:2008-02-26  
是的,js放在jar包
0 请登录后投票
   发表时间:2008-02-26  
leadyu 写道


它不仅仅可以监控j2ee工程(包括EJB以及WebModule)的所有的jdbc调用,包括调用的堆栈(什么程序打开的连接),还可以监控方法的调用,以及http的请求,所有的这一切,只需要部署一个jar,以及配置一个配置文件。



你提供的功能jamon都有,但是你的界面看起来更好看,更耐看一点,赞一个。
jamon的界面太差劲了
0 请登录后投票
   发表时间:2008-02-26  
jamon我了解不多,所以不好说,jwebap目前jdbc,method,http三个功能的plugin,应该说是jwebap-core初步完成以来实现的第一个扩展plugin的例子。

jwebap前期更专注于实现core部分,类静态增强,轨迹容器,和plugin管理,当core逐步成型后,我打算,把精力移到plugin这方面来,由于plugin我可以针对平台来做,所以,慢慢功能强大的多。

现在,有不少想法,初步打算实现的plugin:内存监控plugin,和JVM Reviewer。

后面,我还会开发一些基于测试人员使用的Debug的plugin。


总结:我希望jwebap一直能够做到针对不同人群和环境按需使用,同时在功能不断庞大后还能保持较轻的架子,这是一个好的profiling应该重视的
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics