2

我使用 python 和 Flask 框架编写了一个 Web 应用程序,并使用 mod_wsgi 在 Apache 上设置它。今天我使用 JMeter 对这个应用程序进行一些负载测试。对于一个网址:

  • 当我只设置1个线程发送请求时,响应时间为200ms

  • 当我设置20个并发线程发送请求时,响应时间增加到超过4000ms(4s)。这是无法接受的!

我试图找出问题所在,所以我在烧瓶的 before_request 和 teardown_request 方法中记录了时间。事实证明,处理请求所花费的时间刚刚超过 10 毫秒。

在这个 URL 处理程序中,应用程序只是在 Mysql 数据库中执行一些 SQL 查询(大约 10 个),没什么特别的。

为了测试问题是否出在 Web 服务器或框架配置上,我在同一个烧瓶应用程序中编写了另一个方法 Hello,它只返回一个字符串。它在负载下表现完美,响应时间为 13 毫秒,20 线程并发。

在进行负载测试时,我在服务器上执行“top”,大约有 10 个 apache 线程,但 CPU 大部分是空闲的。

我现在无计可施。即使请求是串行执行的,性能也不应该如此急剧下降......我的猜测是在我不知道的地方有一些排队,除了处理请求之外,肯定还有开销。

如果您有调优 Web 应用程序性能的经验,请帮助!

编辑

关于apache的配置,我用的是MPM worker模式,配置:

<IfModule mpm_worker_module>
    StartServers          4
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadLimit          64
    ThreadsPerChild      50
    MaxClients          200
    MaxRequestsPerChild   0
</IfModule>

至于 mod_wsgi,我尝试打开和关闭 WSGIDaemonProcess(通过注释掉以下行),性能看起来是一样的。

# WSGIDaemonProcess tqt processes=3 threads=15 display-name=TQTSERVER
4

2 回答 2

1

恭喜!您发现了性能问题 - 而不是您的用户!

分析 Web 应用程序的性能问题通常很困难,因为有很多活动部件,而且在运行时很难看到应用程序内部。

您描述的行为通常与瓶颈资源相关联 - 当存在无法跟上的特定资源时会发生这种情况,因此将请求排队,这往往会导致响应时间出现“曲棍球棒”曲线 - 一旦你达到目标在这个资源跟不上的地方,响应时间会很快增加。

20 个并发线程似乎很少发生这种情况,除非你在页面上做了很多非常繁重的工作。

首先要开始的地方是 TOP - 当 CPU 很低时,内存、磁盘访问等在做什么?您的数据库是否在同一台机器上运行?如果不是,TOP 在数据库服务器上说什么?

假设这不是一些愚蠢的硬件问题,下一个最可能的问题是该页面上的数据库访问。当您想要的只是一条记录时,可能是一个查询实际上返回了整个数据库(这是 ORM 解决方案中相当常见的反模式);这可能导致您描述的行为。我会使用 Flask 日志框架来记录您的数据库调用(开始、结束、返回的记录数),并在那里查找异常情况。

如果数据库在负载下表现良好,则要么是框架,要么是应用程序代码。再次,在代码中使用日志语句来跟踪各个代码块的执行时间,并继续寻找......

它并不迷人,而且可能非常乏味 - 但在上线之前你发现它要好得多!

于 2012-11-01T16:32:56.140 回答
0

看看使用 New Relic 来确定瓶颈在哪里。在我的演讲中查看它的概述和关于识别瓶颈的讨论:

http://lanyrd.com/2012/pycon/spcdg/

还要编辑您的原始问题并添加您正在使用的 mod_wsgi 配置,以及您使用的是 Apache prefork 还是 worker MPM,因为您可能在那里做一些非最佳的事情。

于 2012-11-01T23:45:57.070 回答