进行Web应用程序负载测试的步骤 – 案例分析

首先

负载测试非常重要,但是否有可能因为发布时间表优先而被推迟或省略呢?
特别是近年来,由于基于云端运行的前提条件,可能导致事前负载测试被忽视,因为它被认为在发布后进行扩容和横向伸缩更容易。

然而,在某个项目中,我们进行了负载测试,发现它确实很重要,因此以自我警戒的态度,我们将从负载测试的实施开始记录性能调优的流程。
我打算随时添加我参考的链接,以便详细介绍每个工具。
以下数字仅为示例,并进行了适当近似处理。

由于对负载测试的轻视可能会导致的情况

容易想到的事情

    • サービスの継続に必要なサーバリソースが予算またはサービスの収入を上回った。(ワーストケース)

 

    • サービスの継続に必要なサーバリソースが膨大であるため管理がめんどくさい。(まだまし)

 

    • もうこれ以上スケールアップ可能なサーバが存在しない。(あるある)

 

    • パフォーマンスチューニングしたが、リリース後なのでシステムの刷新にコストがかかる。(あるある)

 

    サーバ構成に過不足があって無駄なコストを支払っていた。

如果有一个不需要进行负载测试的服务,我认为这些内容很容易想到,因为它已经考虑在内了。
→ 只要有可扩展的架构,大多数通过金钱解决的问题都可以解决。

除了以上列出的实际可能发生的事情外

    • 構成する各サーバのスケールアップをしてもパフォーマンス改善にほとんど結びつかなかった。

 

    構成する各サーバのスケールアウトをしてもパフォーマンス改善にほとんど結びつかなかった。

→ ※实际上,我们已经构建了一个无法扩展的应用程序!

换句话说,负载测试的目的不仅在于测量系统的极限性能,还包括对整个系统进行调优,确保系统具备可扩展的配置。

本章:负载测试案例研究

目标系统结构.

我们将在AWS上构建以下系统,并从Jmeter服务器进行攻击。

    • ELB

 

    • EC2 Webサーバ Apache + PHP

 

    • EC2 Jmeter攻撃サーバ ※jmeter-serverを起動

 

    • ElastiCache * 2 (Memcached)

 

    RDS (MySQL)

在这种情况下,使用情况将使用CloudWatch进行监控,为了获取每分钟的详细信息,我们将启用详细监控功能(额外收费)。

在开始施加负载之前,先合理地设计一个场景试一试。

请设置一个几乎静态的文件,并查看其吞吐量和各个服务器的资源使用情况。
例如,可以设置一个名为uniqid.php的文件,其中只包含uniqid();的返回值,并通过调用它来检查。

JMeter选项

オプション値スレッド数100ループ回数100Ramp-Up10

实际执行结果示例

labelsamplesAveragemedium90%lineMinMaxErrorThrouputKB/secuniqid10000861041776016434合計10000861041776016434

资源使用情况示例

台数CPU使用率Jmeterc3.xlarge11%Webc3.xlarge110%RDSm3.large10%ElastiCachet1.micro10%

这个结果该如何解读?

尽管所有服务器的资源都有空闲,但吞吐量(164req/sec)明显很差,因此当前状态下无法施加正常负载。
我们将提出可能的假设,并逐个排除来进行进一步研究。

关于应用程序可能存在问题的可能性

由于这次考试是最简单的模式,所以我将跳过这一项。

关于基础设施可能存在问题的可能性

只要JMeter攻击服务器的负载很低,为了排除网络问题,将JMeter攻击服务器构建为Web服务器,并对本地主机进行攻击。
→ 结果几乎没有改善。

有可能是Apache的配置存在问题。

→ 我嘗試過更改同時連接數,但改善幾乎不明顯。

关于考试情景可能存在问题的可能性

在最初的方案中,我们在“通过树形结构展示结果”选项里只对错误进行了检查并使用。但是通过禁用此功能,整体吞吐量得到了改善。
由于没有显示错误时的检查结果,我们原本认为这不会对负载造成影响。但是根据从新加坡区域构建的服务器传输至日本的Jmeter客户端的负载情况来看,这个功能实际上是拖了我们的后腿。

例子的执行结果

labelsamplesAveragemedium90%lineMinMaxErrorThrouputKB/secuniqid1000086104177601200250合計1000086104177601200250

资源使用情况示例

台数CPU使用率Web兼Jmeter攻撃c3.xlarge198%RDSm3.large10%ElastiCachet2.small20%

你如何解读这个结果?

由于Web服务器存在CPU瓶颈,所以该系统的极限值无法超过每台Web服务器1200req/sec。
建立应用程序的性能评估将取决于能否接近这个数值。

重新为原始系统准备Jmter的脚本。

执行结果示例

labelsamplesAveragemedium90%lineMinMaxErrorThrouputKB/secpage11000058411501381602501310page2100004311214291607101324page310000510111708160270139page410000468111448110630136page5100005562327917160420136page61000060415501712200470137page71000061325502619200600135page810000718295042212010001310page91000073527504420160580137page101000075526504218160790139合計100000597235014820100012994

资源使用情况示例

台数CPU使用率Web兼Jmeter攻撃c3.xlarge120%RDSm3.large110%ElastiCachet2.small235%

这个结果该如何解读?

    • どのリソースのCPUもボトルネックになっていないのに全体的なスループットが低すぎる。

 

    • 特徴的なのは、midiumの応答時間は速いのに、90%lineとMaxが非常に悪い。(memcached接続またはDB接続等の外部リソースの接続待ちの可能性が高い。)

 

    • ここには記載していないが、CPU負荷以外も特にボトルネックが見当たらなかった。

 

    最適なアプリケーションであれば、Jmeterで負荷をかけ続けているのでどこかにリソースの逼迫が見えるはず。

这样下去,Web服务器和RDS的扩展和扩容可能都变得毫无意义。
→为了测试,我们改变了实例类型进行了测试,但吞吐量几乎没有变化。

由于网络配置问题和Jmeter场景问题已经解决,因此剩下的可能是应用程序问题,决定引入性能分析工具进行调查。

引入xhprof。

使用PHP的性能分析工具「XHProf」的方法等,通过各种谷歌搜索适当地进行安装。为了可视化,我还安装了graphviz,但是在使用yum安装后发生了分段错误,于是奇怪地通过yum安装32位版本后,正常运行了。

发现PDO::connect()和Memcached::connect()有时候会非常耗时。

MySQL连接的持久性

将数据库连接改为使用pconnect,仅此一项就将吞吐量从129req/sec提升至170req/sec左右。即使查看资源,同时连接数已经附着到请求数上,而新连接数却急剧减少。

Memcached连接的持久化

在比较PECL::Memcache和PECL::Memcached之后,由于PECL::Memcached更受好评,我选择使用了PECL::Memcached。然而,在一篇文章中发现,PECL::Memcached的持久性可以通过指定Memcached::connect(“连接字符串”)来实现。尽管我尝试了这种方法,但实际效果几乎没有改变。更糟糕的是,在我的环境下出现了分段错误,所以我决定放弃使用PECL::Memcached。

我尝试安装PECL::memcache后,吞吐量显著改善。从每秒170个请求到接近500个请求。

查看资源时,与其同时建立连接的数量替代了请求的数量,而新建连接的数量大幅减少。

这种情况下资源的使用情况的例子

台数CPU使用率Web兼Jmeter攻撃c3.xlarge180%RDSm3.large135%ElastiCachet2.small28%

尽管吞吐量有所提高,但由于新连接数急剧减少,导致RDS和ElastiCache的负载降低。

考虑到这个状态下可能存在Web服务器的CPU瓶颈,我们可以尝试增加Web服务器兼攻击服务器。

台数CPU使用率Web兼Jmeter攻撃c3.xlarge280%RDSm3.large190%ElastiCachet2.small212%

虽然负载转移到了RDS上,但吞吐量却达到了两倍的每秒1000个请求。
通过增加Web服务器,整体吞吐量线性地得到了提升。
要进一步提高吞吐量,似乎可以通过升级RDS服务器来实现。

最终的感受

    • jmeter-server(攻撃サーバを複数立てる方式)を初めて試してみたが、いい感じ。(ここでは書きませんでしたが、jmeter-clientとバージョンを合わせる必要があったり、portを開けたりする必要はあります。)

 

    • 上記jmeter-serverの利用に関してはクラスメソッドさんのSpotInstanceとJMeterを使って400万req/minの負荷試験を行うの記事が熱いです。参考にさせて頂きました。

 

    • 負荷試験をやらなかったら、Webサーバ一台あたりで本来の能力の数分の1しかこなせなかったということで、冷やっとしました。

 

    • xhprof + graphbizでのプロファイリングはなんか眺めているだけで楽しい。

 

    高負荷時には永続的接続は超重要

广告

本文的内容是因为这篇文章,经过曲折经历,最终出版了一本关于负载测试的专业知识的书籍。虽然价格略高,但是这本书主要介绍了云端设计、负载测试和负载防护方面的入门知识,对于对此感兴趣的人来说,请务必阅读一下。

广告
将在 10 秒后关闭
bannerAds