当前位置: 首页 > 图文教程 > 服务器 > Linux服务器 > 应用程序跟踪对性能改变进行量化分析

Linux服务器
Linux上双网卡绑定方法(Suse9SP3)
Linux操作系统调优参数的意义
Linux下使用SSH客户端及其Sftp文件传送
教你恢复被误删除的Linux文件
SQL Server注入大全及防御
Linux无法解析域名的解决办法
Linux系统下安装和配置MyEclipse的方法
Ubuntu下VirtualBox 1.4.0设置文件共享
Windows与Linux系统共享StarDict字典文件
修改Linux下相关的登陆信息
Windows通过SecureCRT远程登录Linux主机
Linux操作系统如何修改SWAP交换区的大小
Linux操作系统下为Apache目录添加密码
Linux时间设置与同步(NTP)
Linux内核补丁AMD旁路转换缓冲(TLB)错误
Linux架设DHCP服务器的方法
Fedora 8下Apache配置与管理
Linux操作系统下用单网卡捆绑双IP的方法
Ubuntu Linux系统环境变量配置文件
SUSE Linux中将Tomcat作为Service运行

Linux服务器 中的 应用程序跟踪对性能改变进行量化分析


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-18   浏览: 142 ::
收藏到网摘: n/a

使用ApacheWeb服务器作为示例,以了解如何分析公共配置的性能含义。使用应用程序跟踪来观察应用程序运行过程中进行的系统调用。通过统计调用的次数和发生的时间,您可以轻松地了解性能改变的影响。

您可以对应用程序进行跟踪,以找出它们暂停或不运行的原因。并且可以使用同样的方法,了解更多关于应用程序的信息并理解某些配置的性能含义。因为Apache非常流行并且大多数读者对它都比较熟悉,所以本文使用Apache作为示例。Apache所进行的每次系统调用都会对Web页面的提供带来延迟,通过跟踪不同配置下的Web服务器,您可以确定具体配置的影响。

应用程序跟踪概述

在应用程序的执行过程中,当需要打开文件、发送数据包或者使用系统资源时,它会对基础操作系统进行相应的系统调用。跟踪应用程序意味着可以在调用发生时观察到这些系统调用,这将使得您能够深入地了解该应用程序的行为。在Solaris和IBMAIX®操作系统(AIX)中,使用truss命令完成这项任务,而在Linux®中则使用strace。清单1显示了对pwd命令进行跟踪的示例。


清单1.跟踪pwd命令-bash-3.00$trusspwd...getcwd("/export/home/sean",1025)=0/export/home/seanwrite(1,"/export/home"..,18)=18_exit(0)

在删除开始处与加载该应用程序相关的输出内容后,您可以看到所进行的三次系统调用:

  1. getcwd返回当前工作目录。输出内容中显示了字符串“/export/home/sean”返回到缓冲区。
  2. write可以显示给定的字符串。因为在其执行之后才显示这个系统调用,所以先输出了它的执行结果。还可以注意到,write系统调用的结果是写入字符的个数数目,在这个示例中为17加上一个回车。
  3. _exit使用错误代码0退出该程序,这个错误代码通常表示成功结束。

尽管这是一个很简单的示例,但它演示了通过应用程序跟踪可以观察程序内部机制的程度。有关跟踪方面更深入的信息,请参见参考资料部分。

Apache配置的简要介绍

可以通过一个名为httpd.conf的文件对ApacheWeb服务器进行配置。清单2显示了一个简单配置中的部分内容。


清单2.示例httpd.conf
DocumentRoot"/var/apache/htdocs"<Directory/>OptionsFollowSymLinksAllowOverrideNone</Directory><Directory"/var/apache/htdocs">OptionsIndexesFollowSymLinksMultiViews</Directory>

第一行定义了在何处可以找到HTML文件。将所有的请求都映射到这个目录。如果请求/project/charter.html,将使用/var/apache/htdocs/project/charter.html提供该页面。httpd.conf中剩余的部分由两个Directory节组成。<Directory...>和</Directory>之间的任何内容都将应用于指定目录及其所有的子目录。在本例中,第一节将两项设置应用于根目录,而第二节则指向/var/apache/htdocs。

如果多个节应用于单个请求,那么将会对这些命令进行组合,并且最适合的目录具有高优先级。例如,将使用/var/apache/htdocs/project/charter.html提供/project/charter.html请求的页面。/var/apache/htdocs是/的子目录,所以OptionsIndexesFollowSymLinksMultiViews来自第二节,AllowOverrideNone来自第一节。

可以对许多内容进行配置,并且每项内容都具有其性能含义。本文余下的内容重点关注于如何对这些改变的影响进行量化分析。

建立基准

在您进行任何调整之前,务必要了解系统当前的运行方式。使用-X参数启动Apache,这个参数将强制Apache进入单进程调试模式。这样做可以确保将请求发送到正在进行跟踪的进程,并且消除常规进程间通信所带来的开销。

在守护进程启动之后,通过运行ps-ef找到相应的进程ID,并查找httpd守护进程。在找到该进程之后,使用truss-c-pPID附加到该进程。-c选项表示对系统调用进行计数,而不是逐个显示它们,而-p则表示将跟踪器附加于一个正在运行的进程。

使用Web浏览器请求文档。在页面加载之后,回到truss应用程序,然后按Ctrl-C以结束计数。对于静态HTML页面,您应该看到如清单3所示的内容(为使这些数字变得更有趣,本示例进行了100次相同的请求)。


清单3.系统调用基准
sunbox#truss-c-p15026(maketheWebrequest100times)^Csyscallsecondscallserrorsread.009200write.020200close.020200time.004300alarm.0181100fcntl.009300sigaction.007400munmap.007100llseek.001100pollsys.005100mmap64.008100stat64.007100open64.006100accept.019100getsockname.002100setsockopt.002100------------------systotals:.14936000usrtime:.120elapsed:8.960

truss返回系统调用的列表、执行调用耗费的总时间、调用的次数和任何发现的问题。在这个报表的结尾处,返回了这些系统调用耗费的总时间,以及执行应用程序所耗费的时间。对于这些目的来说,所耗时间是没有意义的,因为它指的是从启动truss开始到其结束的时间,而与Web请求没有任何关系。

清单3显示了最简单的情况。在来自Web浏览器的连接请求到达后,accept系统调用完成该连接。Web服务器使用read调用获得请求的内容,将请求的内容映射到磁盘上的文件。Web服务器首先使用stat64验证该文件是否存在,使用open64打开该文件以便进行读取,然后使用mmap64将该文件的内容映射到内存中。然后使用write将这个文件发送回客户端,使用另一个write生成日志文件,并且服务器执行来自浏览器的最后一个read。该列表中其余的调用都是系统开销,并且当配置发生改变时,不会有显著的变化。

解释这些数值

100次请求总共耗费0.269秒(0.149+0.120),这样的性能相当不错,并且该服务器每秒钟应该可以提供大约370个页面(100/0.269)。但是不能完全相信这些数值,因为它们仅表示进程耗费在CPU上的时间,而不是其真正的执行时间(也称为时钟时间)。还有更多的因素需要考虑,如磁盘和网络的速度、计算机上正运行的其他内容、该守护进程运行于调试模式的事实。您还需要考虑系统调用跟踪本身的开销。

本文中使用的方法重点关注这些操作的相对计时和使用应用程序跟踪消除浪费掉的操作。如果您需要了解Web服务器每秒可以提供的页面数目,参考资料部分中有相应的软件链接,它可以帮助您确定该数值。

跟踪AllowOverride范围

Apache允许管理员通过.htaccess机制将配置权委托给个别的用户。.htaccess是一个包含附加配置指令的文件,如果在httpd.conf中通过AllowOverride配置了请求的目录,那么Web服务器将搜索这个文件。清单4显示了前面的配置了AllowOverrideLimit的配置信息,它允许用户获取访问Web页面的用户名和密码。


清单4.配置了AllowOverride的示例httpd.confDocumentRoot"/var/apache/htdocs"<Directory/>OptionsFollowSymLinksAllowOverrideLimit</Directory><Directory"/var/apache/htdocs">OptionsIndexesFollowSymLinksMultiViews</Directory>

重新启动httpd守护进程并再次运行这些测试,其结果如清单5所示。


清单5.开启了AllowOverrideLimit的100次请求的结果
sunbox#truss-c-twrite,read,open64,stat64,mmap64-p21136^Csyscallsecondscallserrorsread.012200write.021200mmap64.007100stat64.007100open64.022500400------------------systotals:.0721100400usrtime:.141elapsed:16.660

初看起来,系统调用耗费的时间下降了,但这是因为使用了-t选项将跟踪任务限制于一些有意义的系统调用。大多数系统调用并没有发生变化,但现在有500次open64调用,其中有400次返回了错误。执行open64的时间增加了(从0.006秒增加到0.22秒),同时用户空间部分的时间也增加了(从0.12秒增加到0.141秒)。

时间增加是因为Apache现在必须完成附加的工作以处理该请求,即使没有配置重写。单独的AllowOverrideLimit配置明显地增加了开销。问题依然存在,即什么导致了这些错误?要回答这个问题,可以跟踪单个Web请求,如清单6所示。


清单6.确定open64调用失败的原因
sunbox#truss-topen64-p21136open64("/.htaccess",O_RDONLY)Err#2ENOENTopen64("/var/.htaccess",O_RDONLY)Err#2ENOENTopen64("/var/apache/.htaccess",O_RDONLY)Err#2ENOENTopen64("/var/apache/htdocs/.htaccess",O_RDONLY)Err#2ENOENTopen64("/var/apache/htdocs/test.html",O_RDONLY)=5

清单6显示了当请求进入时,Apache对每个指向/var/apache/htdocs的目录进行检查并尝试打开.htaccess文件,但是因为AllowOverride配置为根目录,所以这个文件并不存在。Apache必须在每个子目录中查找.htaccess文件的重写信息,并对它们进行处理。这样一来,由于额外的系统调用、更多的用户空间开销和额外的磁盘活动,从而进一步增加了延迟。对于100次请求来说,增加零点几秒的时间看起来并不是很明显,但是对于一台繁忙的服务器,就会增加更长的延迟。

既然您了解了重写的范围,那么理想的解决方案是不允许重写,并且强制在httpd.conf中对所有的内容进行配置。如果失败,可以将配置的范围限制于需要它的目录。在这个研究示例中,把AllowOverrideLimit放到第二个Directory节中,这将仅添加一个额外的open64调用,以便在/var/apache/htdocs中查找.htaccess。对所有的父目录进行搜索是浪费时间,因为在这个配置中,不会使用其中的任何文件来提供页面。

研究主机名查找

当Web服务器接收到一个请求时,它所知道的关于客户端的信息只有其IP地址,如129.42.42.212对应于IBM.com。然而,Web服务器并不知道这个地址来自于IBM.com,因此,它必须进行反向DNS查找。这样做需要耗费一定的时间,如果在发送请求之前需要这个名称,那么将会延迟对客户端的响应。过去,Apache在缺省情况下会执行这些反向查找,但现在这种行为已经有了改变。

还有另一种情况,其中必须进行反向DNS搜索。当基于主机名(而不是IP地址)配置访问限制时,Apache必须首先将IP地址反向解析为相应的主机名,然后再次将主机名解析为IP地址,以确保它们正确匹配。因为反向域名搜索可以由地址块所有者确定,所以要防止IP欺骗的发生,必须进行第二次查找。可以通过应用程序跟踪来确定DNS解析的影响吗?

要对其进行测试,可以从前面的示例中删除AllowOverrideLimit,然后添加Allowfromibm.com代替缺省的Allowfromall。然后,对DNS服务器进行更改以便向您的工作站返回something.ibm.com,确保初始反向检查能够成功并且随后的正向查找必须通过Internet完成。在示例运行过程中,对保护的Web服务器的请求耗费了15秒的时间。相反,使用IP地址代替ibm.com所耗费的时间小于半秒钟。清单7显示了在使用DNS确保安全时,对一些系统调用进行统计。


清单7.通过主机名进行限制的Web请求的truss输出
bash-3.00#truss-c-p26089^Csyscallsecondscallserrorsread.0005write.0003open.0002close.00110time.0003stat.0005alarm.0008fcntl.00072sigaction.0003sysconfig.0005pollsys.0015door_info.0002stat64.0001open64.0002so_socket.0015accept.0001connect.0025recvfrom.0002send.0015getsockname.0001setsockopt.0001------------------systotals:.011812usrtime:.004

truss报告了该进程所耗费的时间远远小于客户端感觉到的时间(0.015秒与15秒)。这是因为大多数套接字操作都是异步地进行的,其中套接字进行轮询以检查数据是否出现,而不是使得应用程序处于阻塞(等待)状态以等待响应。如此一来,应用程序在等待结果的时候不会消耗CPU时间。这就解释了truss报告的时间和客户端感觉到的时间之间出现差异的原因。

truss并没有忘记所做的更改,0.015秒比本文中研究的第一个简单示例要高一个数量级。从系统调用计数中可以看出,有一些以前没有出现过的调用,包括read、write、close和stat。以及还有send、connect、so_socket和pollsys,这些系统调用用于进行名称请求。因为名称解析可以来自于不同的来源,包括本地文件系统和名称缓存守护进程,所以必须对这几个位置进行检查。在随后的调用中,请求时间小于1秒,这是因为对DNS信息进行了缓存。

最后,大部分的延迟来自于远程名称服务器和正向解析。这个事实进一步强调了,如果您希望依赖于名称查找,那么就需要使用DNS缓存和快速DNS服务器。然而,最佳的解决方案是使用一种可选的方法来处理这个问题。一种比较简单的解决方案是指定IP地址块(如Allowfrom10.0.0.0/8),这种方法比DNS查找要快得多。因为反向和正向查找必须匹配,所以对名称进行的操作,很可能可以用于网段。另外,Apache可以集成各种身份验证系统,所以基于用户的身份验证是另一种可选方法。

系统调用与库调用

如果熟悉套接字编程,那么您可能会寻找gethostbyname和其他类似的调用,这些调用都可以用来执行主机查找功能。有一些库调用,由/usr/lib中的系统库libc和libsocket提供。库调用封装了一个或多个系统调用,以及额外的逻辑。您可以将它们作为程序员友好的接口来进行系统调用。例如,gethostbyname库调用将执行许多步骤,以便根据服务器的配置查找相应的名称,如检查/etc/hosts或搜索网络信息系统(NIS)或DNS。这些步骤包含了内核所提供的更小的构件,即系统调用。在大多数这样的这种情况下,两者之间的差别通常很小。truss还可以跟踪库调用,但是无法提供像系统调用那样详细的信息。

结束语

监视和统计系统调用的功能不仅有助于进行故障排除,还有助于理解应用程序配置如何对性能产生影响。与系统的其他部分之间的每个交互操作都会调用一个或多个系统调用,并且每次调用都会增加系统开销。这并不是说系统调用非常糟糕,如果程序员不与其他的部分进行交互,那将是很乏味的。相反,在改变应用程序时,您可以监视系统调用的使用,以便更好地了解这些改变对总体性能的影响。

原文链接:http://www-128.ibm.com/developerworks/cn/aix/library/au-perftun.html

上一页[1][2]