诊断应用数据库的性能瓶颈.docx

上传人:b****5 文档编号:4501240 上传时间:2022-12-01 格式:DOCX 页数:26 大小:271.90KB
下载 相关 举报
诊断应用数据库的性能瓶颈.docx_第1页
第1页 / 共26页
诊断应用数据库的性能瓶颈.docx_第2页
第2页 / 共26页
诊断应用数据库的性能瓶颈.docx_第3页
第3页 / 共26页
诊断应用数据库的性能瓶颈.docx_第4页
第4页 / 共26页
诊断应用数据库的性能瓶颈.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

诊断应用数据库的性能瓶颈.docx

《诊断应用数据库的性能瓶颈.docx》由会员分享,可在线阅读,更多相关《诊断应用数据库的性能瓶颈.docx(26页珍藏版)》请在冰豆网上搜索。

诊断应用数据库的性能瓶颈.docx

诊断应用数据库的性能瓶颈

诊断应用数据库的性能瓶颈

时间:

2004-07-22

作者:

PeterChapman, RiniGahir

浏览次数:

3137

本文关键字:

JDBC, 性能, 监控, EJB, 瓶颈, 数据库

文章工具

 推荐给朋友

 打印文章

J2EE的崛起

  J2EE作为Web应用开发的标准企业计算平台面世,其实力越来越强大,日益普及。

J2EE支持遗留应用程序和接口、多种操作系统、分布式和群集式环境,以及高量关键任务应用程序,同时支持安全和管理与监控。

  通过提供一种开发分布式、可伸缩应用程序的框架和蓝图,J2EE使公司及其开发者能够集中注意力去编写模块化的定制应用程序代码,并且不必担心安全、资源管理和可伸缩性的细节。

  行业领先的应用程序服务器,例如BEAWebLogicServer,能提供许多功能和服务。

多个WebLogic服务器实例的群集和故障恢复功能提供了可靠性、可用性和可伸缩性。

它们也提供诸如安全和资源管理之类的其他服务,例如执行线程池、EJB高速缓存和JDBC池。

第三方所写的Java数据库连接(JavaDatabaseConnectivity,JDBC)驱动程序进一步抽象和简化不同数据库管理系统(DBMS)间数据存取的编码。

  这就是一个强大的平台,该平台能够大大简化并且抽象开发分布式、高量企业应用程序的低层细节。

J2EE性能的挑战

  听上去没有什么会出问题,是吗?

的确如此,除了应用程序不能达到最终用户或者服务级协定所要求的性能标准之外。

一个开发项目和商业创新是否成功要视其迅速检测、诊断和解决这些性能问题的能力而定。

  由于它们的复杂性日益增加,与早期的僵硬应用程序环境相比,在这些多层的、分布式J2EE应用程序中的性能瓶颈更难以诊断。

J2EE环境包含多层相互连接的软件和硬件组件,它们相互作用,满足任何既定的最终用户请求。

性能团队的成员——设计师、开发者、应用服务器管理员和数据库专家——他们有自己对系统的见解,而且可能拥有他们自己的经验仓库或者“设备中心”的诊断工具。

但是这个团队的成员怎样一同工作将问题分离出来呢?

如果没有对J2EE系统所有组件的全面广泛的了解,如果他们不能相互交互,那么一位性能专家怎样找出哪台服务器速度慢?

哪个组件速度慢?

哪种资源不足?

数据库引擎是主要瓶颈,还仅仅是一个次要因素呢?

  这种挑战可能会使无准备的人或装备不良的人畏缩不前。

这种困惑可能使团队的成员焦头烂额,或者更严重时,他们会任意指责过失。

“是应用程序,还是数据库?

  公司里最常见的挫折就是面对表现不佳的分布式J2EE应用程序感到困惑:

“它是应用程序,还是数据库?

我们应该从哪里开始修理?

”通常情况下,会有人斗胆作出一种推测,不再继续在浩繁的代码寻找错误的或者低效率的算法,或者放弃彻底搜寻SQL语句和数据库表格的作法。

换句话说,他们挑出应用程序或者数据库(或者在最坏情况下,两个都选),并努力将从谜团中分离出来的片断最优化。

  令人遗憾的是,这种解决问题的观点经常是过度简化的,这是因为应用程序、数据库、WebLogicServer都不是在孤立地运转。

对这个问题的一种综合解决方法需要提高对这个相互联系的系统内所有三个部分的能见度:

WebLogic资源利用和配置、应用程序架构以及数据库查询的执行,而且包括基本的硬件基础设施性能。

  有了对这些子系统相互作用的了解,性能团队的成员就能有效地分离有问题的组件,并将问题交给正确的职能专家进行处理。

对相互之间关系的了解是关键

  在此,了解和相互关系是两个关键词。

没有这两个关键词,检测和根除的要求就使诊断极其艰难。

  我们需要了解WebLogic服务器运行时JMX的性能度量。

我们需要了解SQL查询的计时和结构,以及数据库引擎所运行的存储过程。

而且最重要的是,我们需要了解最终用户发出的请求在跨越整个分布式系统时的端到端计时,而且所有的组件要与JDBC连接池交互,DBMS的调用要以显式的基于单个请求的方式来制定。

  我们不仅需要了解方法层级的应用程序计时,而且需要了解每个组件与其他组件相互作用形成应用程序架构的方式。

大多数J2EE性能监视工具所提供的分离度量方法和JDBC计时都脱离了应用程序架构,所以几乎是没有用的。

分离的SQL语句执行响应次数也是如此,脱离了该语句产生的位置、被调用的次数或者与其最终用户请求的数据库的相互作用,几乎也是没有用的。

  理想的工具解决方案对定制的J2EE应用程序与WebLogic服务器资源和DBMS相互作用的方法提供深入的洞察,并提供对这些相互作用怎样影响每个最终用户事务的总响应时间的深入理解。

这些相互作用的高级表现概述如图1。

典型的应用数据库性能瓶颈

  现在或许你正在想:

“现在理论知识足够了,我怎样修复我的应用程序呢?

”下面的章节将讨论性能瓶颈的三个主要类型,它们是通过测量和分析许多现实世界的J2EE应用程序的性能后提炼出来的,包括几个卓越的金融、电信、以及“财富100强”制造业公司的J2EE系统。

这绝不意味着它是一个毫无遗漏的列表,或者是一个可以用来调优任何应用程序的、一步一步遵循的“调试清单”。

由于分布式的本质和错综复杂的架构,每个J2EE应用程序都有它自己的独特的性能特点,但是也有一些需要避免的共同的缺陷。

  下面我将介绍应用数据库的三种性能,其中具体的示例是通过运行BEAPetStore示范应用程序收集的,并且采用QuestSoftware的PerformaSure收集和分析性能数据。

过量的数据库调用

“客户”端数据处理和结果集的卷动

  到目前为止,在J2EE数据库应用程序中最严重的性能瓶颈来自从用户应用程序对数据库引擎的过量调用。

这些不必要的额外调用不一定是SQL查询的Execute()或Update(),但几乎总是跟与数据库的其他交互有关,例如ResultSet操作。

一个常见的错误是指定了过于精确的查询条件,然后使用ResultSet.Next()详细地搜寻返回的数据,每次一行。

这种作法会使应用程序的性能由DBMS内的数据集来决定——对于大的表格来说,搜寻量可能是巨大的;我曾见过客户站点的数据所执行的每个SQL查询都向ResultSet.Next()发出了超过50,000个调用指令。

  如果有些数据处理必须在应用程序代码内进行,应考虑从DBMS大批取得所要求的数据,避免让应用程序反复回调数据库,从数据集里取回每一记录。

  例1:

过量的结果集卷动

  图2显示:

当PetStore应用程序内的“commitorder”HTTP请求执行servlet、JSP和EJB代码,并最终调用DBMS的SQL语句时,该请求的PerformaSure重建。

右边彩色编码的标尺表明哪个方法执行迅速(冷蓝色),以及哪个方法是昂贵的热点方法(火红色)。

右边的工具提示提供了请求的全部计时和调用数。

显然,在右边的数据库节点是一个热点,并且需要更进一步的调查。

  通过放大所识别的热点,我们能看出该事务执行的全部JDBC操作的详细计时和调用数,例如打开一个JDBC连接、“SELECT”SQL语句的创建和执行、ResultSet.Next()卷动以及最后还有关闭连接。

EJB方法“GetItem”被调用了7次(对应于7个commitorderHTTP请求),快速运行的SQL语句被执行了7次,并且在ResultSet中移动了672次。

与执行实际查询相比较,过度地与DBMS反复交互反而花费了更多的时间!

这不是一种可伸缩的架构——随着DBMS中的数据集增长,并且随着更多并发的最终用户执行事务,这类性能问题只能会恶化。

两个查询而不是一个查询

  另一个经验法则是将SQL查询和更新的设计留给数据库专家,因为他们对各种各样的表格大纲和索引非常熟悉。

编写EJB的开发者往往对他(或者她)想从数据库引擎获取什么样的数据,或者需要更新什么样的数据有自己的看法。

困难在于怎样编写执行任务所必需的最少、最有效率的查询和更新。

学会只选择在应用程序中真正需要的数据是至关紧要的。

这样,降低了RDMS必须执行的处理数量,并且将查询和网络中发送数据的数量极小化。

  任何基于集合的处理都以DBMS实现最有效,而不是通过网络获取并在WebLogic服务器EJB层的应用程序逻辑内执行处理最有效。

封装应用查询和更新数据的规则及条件的“业务逻辑”保存在EJB层,而实际的实施细节最好由数据库引擎来处理。

低级的查询处理逻辑,例如为临时表选择初始数据,并基于该数据进行进一步的查询,最好由DBMS以存储过程的形式进行处理。

数据库连接池问题(JBDC)

连接池泄漏

  当用户应用程序内的一个组件(通常是一个EJB)从一个连接池请求一个连接、查询或者更新某些数据,最后释放连接失败时,就会发生连接池泄漏。

虽然通过检查WebLogicJMX性能度量(“连接数目”和“等待数目”)以及观察DataSource.GetConnection()缓慢的反应时间,能够很简单地检测到一个连接池迅速达到它的最大连接数目,但是很难在应用程序代码本身内准确指出泄漏的源头。

如果存在多个最终用户请求(因此应用程序代码有多个部分),这些请求从同一个JDBC连接池分配连接,这时找出连接池泄漏更加困难:

到底哪个请求没有释放连接呢?

  为了解决这个问题,需要一个工具,它能够基于单个请求明确地映射应用程序与数据源的交互。

下面的例子展示了PetStore的“CommitOrder”HTTP请求分配和释放与数据源连接的过程。

  例2:

连接池泄漏

  图4显示了两个WebLogicJDBC度量指示连接池泄漏的证据。

第一个图显示连接池的连接数目迅速增加到了连接池的最大数目——400个连接。

在连接池达到最大连接数目的同时,等待连接的请求数量(等待空闲连接的请求数目)不断增加,这表明可能已经发生了连接泄漏。

但是连接泄漏发生在源代码的哪个部分呢?

图5显示了“产品”请求,并且标识了该请求中两个单独的应用程序代码片分配和释放JDBC池的连接。

通过对这些区域的快速分析提供了关于连接池是如何使用的详细信息。

  在图5中我们标识的第二个区域内,我们能立即找出性能问题的根源。

在这一时间段内,EJB共调用GetProduct()804次,从而调用executeQuery()804次(工具提示不显示)。

比较getConnection()和Connection.close()的次数,可以看出:

尽管请求JDBC连接1,012次,但是只释放了756次。

那些GetConnection()调用的红色显示的信息和计时信息可以明确证实这将引起性能退化。

值得注意的是,尽管连接泄漏很容易用度量数据加以检测,但是如果多个事务或者在同一事务内的多片代码都在同一个JDBC池内分配连接,那么这些泄漏的代码根源不是无法精确识别,就是难以精确识别。

JDBC连接池的大小

  一个良好的经验法则是测量执行线程池的大小,乘以每个最终用户事务(线程)使用的并发数据库连接平均数,再加上10%的峰值时期负荷。

平均每个事务的连接数通常是一个,无论所需的峰值负荷缓冲区是多大,JDBC连接池和执行队列大小都相同。

通过使用大的JDBC池运行测试,并观察在任何给定的执行队列大小前提下所用JDBC连接池的平均值和峰值,可以反复调整该连接池的大小。

还应该监控调用Database.GetConnection()的时间,以保证没有花太长的时间来等待JDBC资源。

  在生产系统里使用JDBC池时,应牢记的第二点是:

要设置最初池大小总是等于最大连接池大小。

通过这样做,在池中创建所有连接的性能开销都将发生在WebLogicServer启动的过程中,而不是发生在最终用户运行时中。

错误组建的数据库查询

组建不良的SQL语句或者储存过程

  这个常见问题与早先讨论的“两个查询而不是一个查询”的性能瓶颈有关。

在这种情况下,虽然每个最终用户请求仅仅调用一个SQL语句或调用储存过程一次(或者适当的次数),然而仍然需要花费相当多的时间去执行。

幸运的是,很容易用先进的性能工具检测到运行时间长的语句,并且只要确认应用程序与数据库之间有效交互,就可以让数据库管理员调优不合适的SQL语句或者储存过程。

  关键是拥有一种工具,通过拆分具有排他性计时信息和调用次数的每个语句所执行的各个JDBC操作,单个用户就能够排除是应用程序设计导致了问题。

然后,该问题可以交给DBA,DBA使用其特有的DBMS性能工具进一步深入诊断表架构、索引和锁定。

  数据库操作的另一个性能问题是:

在执行存储过程时或者Rollback()完成数据库事务发生错误时抛出的异常。

在我们遇到的几个场景中,对DBA而言,能非常迅速地确定这些异常——即能在比较短的时间里完成确定。

问题是需要了解正在调用应用程序代码中的哪些方法、哪些存储过程正在抛出异常,以及筛选合适的信息传送给合适的专家。

例如,当应用程序需要调用Rollback()和Commit()操作时,前面示例所示的工具提示会提供异常退出信息。

没有有效利用语句缓存

  在应用程序开发期间,当要执行的一个查询的结构已知,但是在运行时将使用不同的参数时,这时最好使用事先准备好的语句,并在运行时将参数传递给语句。

这样可以缓存事先编译好的查询,该查询可以通过WebLogic准备好语句缓存来访问,而不用反复地将其传递给DBMS并在DBMS中进行反复地编译。

  默认值是零——在没有用户修改设置时,不缓存任何语句或者数据。

为应用程序选择的缓存大小的有效性可以通过比较WebLogicJMX性能度量中的“准备好语句缓存的命中率和非命中率”来验证――通常而言,那些高速缓存尺寸应该等于所有最终用户请求类型中通常执行的查询数目。

结束语

  在一个承认频繁前期测试价值的组织内实行这样的经验法则,能够降低花费在无限QA循环上的时间,并且极大的加快应用程序的准备就绪过程。

通过把资源如实地重新组合,使资源能够在硬件架构和期望的最终用户负荷方面密切反映生产环境的分段运输环境,就可以在引起生产问题和使顾客不满意之前检测到许多性能瓶颈,并加以诊断和解决。

  通过部署有效的J2EE性能诊断工具,在分段运输和生产环境过程中,实际上能够消除昂贵的猜测方式和部门指示。

一件有效的工具和解决问题的方法能有效的将各类问题分配给合适的专家或其独有的解决方法工具。

在任何时间减少跟踪性能问题的人数将减少解决问题时的挫折、费用和时间,因此也减少了进入市场的时间。

结果使性能小组和最终用户的满意度都提高了。

工具条

  Quest(软件)的PerformaSure显示定制J2EE应用程序的动态图表映射,并且显示J2EE应用程序如何基于每个最终用户请求使用WebLogicServer资源和数据库管理系统。

其独特的Tag-and-Follow技术能将应用程序的计时和应用服务器的资源度量联系起来,清楚地标识应用数据库的性能瓶颈,并重建那些跨越分布式J2EE系统的端到端事务的执行路径。

QuestPerformaSure应用数据库性能瓶颈数据

  基于每个请求的定制应用程序性能图

  时间花费和如下调用的数目:

  获得和释放一个DBMS连接。

  准备SQL语句,传递参数。

  执行语句。

  操纵返回的结果集。

  提交或者回调一个数据库事务。

  抛出异常。

  WebLogicJMX资源使用度量

  JDBC连接池。

  准备好的语句高速缓存。

  EJB池+高速缓存。

  DBMS执行和更新次数

  SQL语句和存储过程。

  ©2003SYS-CONMedia,Inc版权所有。

 作者简介

PeterChapman是QuestSoftware的一位产品经理。

Peter在软件架构设计和性能调优以及高科技产品管理方面有5年多的从业经验,他主要负责识别市场需要、定义新产品需求、并且制定产品销售策略。

RiniGahir是QuestSoftware的J2EESolutions的产品销售经理。

Rini在ERP、电子商务和软件应用销售方面有5年多的从业经验,他主要负责识别市场需要、定义新技术满足用户要求,并且制定产品开发策略。

性能测试之协议分析

文章出处:

51testing作者:

朴春龙发布时间:

2006-01-18

最近在论坛上的一些朋友问脚本方面的问题,比如用lr的winsock协议录制的脚本遇回放过程中遇到如下错误

Action.c(20):

Error:

callConnect-Can'tassignrequestedaddress.Errorcode:

10049.

Action.c(20):

Error:

Timeoutexpiredwhiletryingtoconnect.Errorcode:

9017.

这里的10049是udp协议错误,是脚本没有和服务器同步,这说明什么问题呢。

下边我用一个协议进行分析,来看看到底是什么问题,

smtp协议分析:

1.SMTP工作方式有两种情况:

一是电子邮件从客户机传输到服务器;二是从某一个服务器传输到另一个服务器.

2.SMTP是个请求/响应协议,命令和响应都是基于ASCII文本,并以CR和LF符结束。

响应包括一个表示返回状态的三位数字代码.

3.SMTP在TCP协议25号端口监听连接请求

4.连接和发送过程:

a.建立TCP连接

b.客户端发送HELO命令以标识发件人自己的身份,然后客户端发送MAIL命令

服务器端正希望以OK作为响应,表明准备接收

c.客户端发送RCPT命令,以标识该电子邮件的计划接收人,可以有多个RCPT行

服务器端则表示是否愿意为收件人接受邮件

d.协商结束,发送邮件,用命令DATA发送

e.以.表示结束输入内容一起发送出去

f.结束此次发送,用QUIT命令退出。

5.另外两个命令:

VRFY---用于验证给定的用户邮箱是否存在,以及接收关于该用户的详细信息。

EXPN---用于扩充邮件列表。

6.邮件路由过程:

SMTP服务器基于‘域名服务DNS中计划收件人的域名来路由电子邮件。

SMTP服务器基于DNS中的MX记录来路由电子邮件,MX记录注册了域名和相关的SMTP中继主机,属于该域的电子邮件都应向该主机发送。

若SMTP服务器mail.withub.org收到一封信要发到pcl@withub.org

a.Sendmail请求DNS给出主机withub.org的CNAME记录,如有,假若CNAME到mail.withub.org,则再次请求mail.withub.org的CNAME记录,直到没有为止.

b.假定被CNAME到mail.withub.org,然后sendmail请求@withub.org域的DNS给出mail.withub.org的MX记录,

shmailMX5mail.withub.org

10shmail2.withub.org

c.Sendmail最后请求DNS给出shmail.withub.org的A记录,即IP地址,若返回值为1.2.3.4

d.Sendmail与1.2.3.4连接,传送这封给pcl@withub.org的信到1.2.3.4这台服务器的SMTP后台程序

这里是协议的一个解析过程,我们要看看,利用lr录制脚本后然后回放,录制的过程中mail.withub.org返回客户端服务器上有多少给用户的邮件,lr把这个数字保存下来,最为下次回放的时候对比。

当你第二次回放的时候,lr模拟客户端发送请求,这时候服务器上没有了新邮件,返回可能是0,lr把这个返回值和当时录制的脚本保存的返回值进行对比(那个时候可能服务器上有3个新的邮件,服务器返回的值是3),明显这个值是动态变化的。

你的脚本如果没有经过修改,肯定是回返不成功的。

那么上边提到的错误信息,同样的道理,我们要分析一下到底是什么问题,从协议上分析,从系统环境上分析。

解决方法,动态关联

1.用同样的用户操作同样的步骤两次,然后用lr工具wdiff进行脚本对比,找出不同的地方!

2.用lr自动关联

3.手工关联,找到要替换的动态数据进行替换

使用LR测试Oracle数据库的方法

使用LR测试Oracle数据库的方法

一个简单的连接方法,欢迎大家跟贴讨论更多方法

详细脚本见附件

选择,建立一个Oracle(2-Tier)协议的脚本

加入

staticLRD_INIT_INFOInitInfo={LRD_INIT_INFO_EYECAT};

staticLRD_DEFAULT_DB_VERSIONDBTypeVersion[]=

{

    {LRD_DBTYPE_NONE,LRD_DBVERSION_NONE}

};

先定义初始化数据库的各种变量

staticvoidFAR*    OraEnv1;

staticvoidFAR*    OraSvc1;

staticvoidFAR*    OraSrv1;

staticvoidFAR*    OraSes1;

staticvoidFAR*    OraStm1;

unsignedlong        rownum;

初始化数据库部分

lrd_init(&InitInfo,DBTypeVersion);

lrd_initialize_db(LRD_DBTYPE_ORACLE,3,0);

lrd_env_init(LRD_DBTYPE_ORACLE,&OraEnv1,0,0);

lrd_ora8_handle_alloc(OraEnv1,SVCCTX,&OraSvc1,0);

lrd_ora8_handle_alloc(OraEnv1,SERVER,&OraSrv1,0);

lrd_ora8_handle_alloc(OraEnv1,SESSION,&OraSes1,0);

连接数据库

lrd_server_attach(OraSrv1,"这里填写数据库的名称",-1,0,0);

lrd_ora8_attr_set_from_handle(OraSvc1,SERVER,OraSrv1,0,0);

设定数据库密码

lrd_ora8_attr_set(OraSes1,USERNAME,"system",-1,0);

lrd_ora8_attr_set(OraSes1,PASSWORD,"这里填写密码",-1,0);

初始化连接session

lrd_ora8_attr_set_from_handle(OraSvc1,SESSION,OraSes1,0,0);

开始连接数据库

lrd_session_begin(OraSvc1,OraSes1,1,0,0);

lrd_ora8_handle_alloc(OraEnv1,STMT,&OraStm1,0);

设定查询语句

lrd_ora8_stmt(OraStm1,"这里填写查询语句",1,0,0);

执行查询语句

lrd_ora8_exec(OraSvc1,OraStm1,0,0,&rownum,0,0,0,0,1);

释放连接数据库的各种变量

lrd_handle_free(&OraStm1,0);

lrd_session_end(OraSvc1,OraSes1,0

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1