【基于P6spy引擎的数据库监控与剖析工具IronTrackSQL】简介
l 背景及意义
n 在我们 Java 开发应用程序的过程中,难免会碰到系统的性能问题,特别在企业应用的开发过程中,都会与数据库进行打交道。当我们碰到数据库性能时,最有效的就是直接跟踪每一个 SQL 语句的执行情况,SQL 语句的优化、索引的优化往往也是最容易取得最直接的效果的.
n 基本上,大部分性能测试与调优空间直接或间接与数据库相关,因此需要一款低性能消耗,无侵入代码的进行数据库操作监控剖析
基于P6spy引擎的数据库监控与剖析工具IronTrackSQL应育而生。
l 效果与反馈
n 从开发角度来看,测试帮助他能够更好定位慢查询,或频率较高的SQL。
甚至在提交测试之前,自己安装并测试,所见即所得,提前优化DB设计,在设计时就考虑DB的性能与伸缩性。
n 从DBA角度,直接抓住SQL瓶颈,发现一个优化一个,不需要再花太多时间理解业务与代码逻辑或跟进文档。
n 从测试角度,提高性能测试效率,降低性能风险,从而提高项目质量。
l 安装配置与使用
P6Spy 支持 JBoss/Tomcat WebSphere、WebLogic、和Resin等绝大多数的应用服务器
n 服务器端配置
1, 下载\\10.20.136.69\public_g\DB监控与SQL解析\p6spy (username/password:software/download)
2, 把 P6Spy 的 jar 包 p6spy.jar 放到 CLASSPATH 中,如果是 Web 应用程序则放在 YourWebApp/WEB-INF/lib/ 目录下;
3, 把 spy.properties 放到 CLASSPATH 目录下,如果是 Web 应用程序放在 YourWebApp/WEB-INF/classess/ 目录下,注意不是 lib/ 目录
4, 修改你应用系统中的数据库驱动名称为 P6Spy 的驱动程序名称 com.p6spy.engine.spy.P6SpyDriver 其它的全部使用默认值,暂时先都不用修改;
5, 打开配置文件 spy.properties 文件,找到 realdriver,把它的值改为你的应用系统的真正的数据库驱动名称;
6, 运行你的应用程序或 Web 应用程序,可以在 spy.log 里看到 P6Spy 监测到的 SQL 详细的执行与操作的记录信息了,包含有完整的 SQL 执行参数。
样例:请参照脚本中startup.sh代码示例。
示例中完成把应用涉及数据库连接的hibernate与springconfig改为p6spydriver,
Spy.properties改为mysql driver,因为我测试的程序是基于Mysql的JDBC连接
同样支持oracle,如下图,其工作原理和配置,参见附后。
n 客户端启动
1, 下载\\10.20.136.69\public_g\DB监控与SQL解析\IronTrackSQL (username/password:software/download)
2, Spy.properties中设置监听端口号 monitorport=2000;
3, 先运行 java -jar irontracksql.jar 来启动 IronTrack SQL;
4, 再启动你的应用程序或服务器;
5, 可以在 IronTrack SQL 图形化的界面上看到结果并进行分析了。
n 工具使用
1, 点击“Config”按钮就可以设置主机名、端口与刷新的时间(毫秒为单位)。根据你的服务器与端口的不同而进行相应地改变,下面以本地和 2000 端口,刷新时间为 500 毫秒为示例。设置完成后,确定,点击“Connect”就可以连接应用系统并进行监测与分析了,当要停止分析时,只要点击“Disconnect”按扭即可立刻停止分析了。
在分析的过程中,我们可以根据需要点击“Purge”按钮,它可以清除目前所监测到的内容,然后重新进行记录监测信息,很方便地进行重新开始
2,分析结果
经过一段时间的系统运行后,我们可以直接得到分析的结果与相应的图形分析示例。相关的信息显示如下:
- Count 列显示 SQL 语句的调用次数;
- Avg Time 列显示 SQL 语句的执行平均时间;
- Max Time 列显示 SQL 语句花费的最高时间;
- SQL 列显示真正执行的 SQL 语句内容。
同时也可以通过设置过滤条件来显示指定条件的结果,比如:只关注平均调用次数大于 100 次 的结果。点击“Filtering”左边的小三角图标,可以显示如下的过滤条件设置栏目:
设置完成后,点击“Apply Filter”按钮即可以获取所需要的相关结果了。这样可以更加方便地集中精力进行所需要的内容分析,可以更加方便快速地定位到问题的所在之处,然后进行解决。
l 工作原理
简单地讲,我们可以认为 P6Spy 就是一个代理(Proxy),它只做了一层对 JDBC 驱动的拦截,然后转发出去,这样的设计与实际的应用程序没有任何的耦合性,除了在配置中将驱动程序改成 P6Spy 的拦截驱动外,程序其他地方并不需要做任何的改变。这层拦截器除了可能会给系统带来略微的性能下降外,对程序其他方面没有任何的影响。而相对于这一点点的性能下降,在开发环境中对于开发人员来说是无法感觉到,相比它所带来的好处,完全可以忽略不计。
P6Spy 对数据库进行拦截监控的处理过程
下表列出了 spy.properties 配置文件中的各配置项的名称、默认值及其意义和相关注意事项:
配置项名称 |
默认值 |
配置项意义及相关注意事项 |
module.log |
com.p6spy.engine.logging. P6LogFactory |
用来拦截和记录任务应用程序的 JDBC 语句。若无配置或注释掉则无此功能。 |
module.outage |
com.p6spy.engine.outage. P6OutageFactory |
检测和记录执行时间比较长的 SQL 语句。若无配置或注释掉则无此功能。 |
realdriver |
|
真正的应用系统使用的数据库驱动程序名称。 |
realdriver2 |
|
真正的应用系统使用的第二种备用数据库驱动程序名称。 |
realdriver3 |
|
真正的应用系统使用的第三种备用数据库驱动程序名称。 |
deregisterdrivers |
false |
显示地把真正的数据库的驱动程序进行反注册掉。取值 true| false |
executionthreshold |
|
P6Log 模块执行时间设置,整数值 (以毫秒为单位),只有当超过这个时间才进行记录 Log。 |
outagedetection |
false |
P6Outage 模块是否记录较长时间运行的语句。取值 true| false |
outagedetectioninterval |
|
P6Outage 模块执行时间设置,整数值 (以秒为单位)),只有当超过这个时间才进行记录 Log。 |
filter |
false |
是否过滤 Log,取值 true| false |
include |
|
过滤 Log 时所包含的表名列表,以逗号分隔。 |
exclude |
|
过滤 Log 时所排除的表名列表,以逗号分隔。 |
sqlexpression |
|
过滤 Log 时的 SQL 表达式名称 |
autoflush |
true |
是否自动刷新。取值 true| false |
dateformat |
|
设置时间的格式,也就是用 Java 的 SimpleDateFormat 程序。 |
includecategories |
|
显示指定过滤 Log 时包含的分类列表,取值为 error,info,batch,debug,statement,commit,rollback,result 的各种组合。 |
excludecategories |
|
显示指定过滤 Log 时排队的分类列表,取值同上。 |
stringmatcher |
|
使用正则表达式来过滤 Log,取值为 com.p6spy.engine.common.GnuRegexMatcher 和 com.p6spy.engine.common.JakartaRegexMatcher |
stacktrace |
false |
打印堆栈跟踪信息。取值 true| false |
stacktraceclass |
|
如果 stacktrace=true,则可以指定具体的类名来进行过滤。 |
reloadproperties |
false |
监测属性配置文件是否进行重新加载。取值 true| false |
reloadpropertiesinterval |
60 |
属性配置文件重新加载的时间间隔,以秒为单位。 |
useprefix |
false |
是否加上前缀,设置为 true,会加上 p6spy: 作为前缀。取值 true| false |
appender |
com.p6spy.engine.logging. appender.FileLogger |
指定 Log 的 appender,与 Log4J 有点同义,取值:com.p6spy.engine.logging.appender.Log4jLogger、com.p6spy.engine.logging.appender.StdoutLogger 和 com.p6spy.engine.logging.appender.FileLogger |
logfile |
spy.log |
指定 Log 的文件名,任何适于操作系统的文件。 |
append |
true |
指定是否每次是增加 Log,设置为 false 则每次都会先进行清空。取值 true| false |
log4j.appender.STDOUT |
org.apache.log4j.ConsoleAppender |
当 appender 为 log4j 时采用的配置,配置如同 Log4J 的相关配置。 |
log4j.appender.STDOUT.layout |
org.apache.log4j.PatternLayout |
同上 |
log4j.appender.STDOUT. layout.ConversionPattern |
p6spy - %m%n |
同上 |
log4j.logger.p6spy |
INFO,STDOUT |
Log 级别的设置,取值同 Log4J 的配置 |
realdatasource |
|
设置数据源 DataSource 的配置名称。 |
realdatasourceclass |
|
设置数据源 DataSource 的类的全称。 |
realdatasourceproperties |
|
设置数据源 DataSource 的属性,以分号分隔。 |
jndicontextfactory |
|
设置 JNDI 数据源的 NamingContextFactory。 |
jndicontextproviderurl |
|
设置 JNDI 数据源的提供者的 URL。 |
jndicontextcustom |
|
设置 JNDI 数据源的一些定制信息,以分号分隔。 |