我使用python和Flask框架编写了一个Web应用程序,并使用mod_wsgi在Apache上进行了设置。 今天我使用JMeter对此应用程序执行一些负载测试。 对于一个网址:
当我只设置1个线程发送请求时,响应时间为200ms
当我设置20个并发线程来发送请求时,响应时间增加到超过4000毫秒(4秒)。这是不可接受的!
我试图找到问题,所以我在flask的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
答案 0 :(得分:1)
恭喜!您发现了性能问题 - 而不是您的用户!
分析Web应用程序的性能问题通常很难,因为有很多移动部件,并且在应用程序运行时很难看到它。
您描述的行为通常与瓶颈资源相关联 - 当某个特定资源无法跟上时会发生这种情况,因此队列请求会导致响应时间产生“曲棍球棒”曲线 - 一旦您达到了这个资源无法跟上的程度,响应时间非常快。
除非你在页面上做了很多非常繁重的工作,否则20个并发线程似乎很少发生。第一个开始的地方是TOP - 虽然CPU很低,有什么内存,磁盘访问等等吗?您的数据库是否在同一台机器上运行?如果没有,TOP在数据库服务器上说什么?
假设它不是一些愚蠢的硬件,下一个最可能的问题是该页面上的数据库访问。当你想要的只是一条记录时,这可能是一个查询从字面上返回整个数据库(这是一个与ORM解决方案相当常见的反模式);这可能会导致您描述的行为。我会使用Flask日志记录框架来记录您的数据库调用(开始,结束,返回的记录数),并查找那里的异常。
如果数据库在加载下运行良好,则它是框架或应用程序代码。再次,在代码中使用日志记录语句来跟踪各个代码块的执行时间,并继续寻找......
它不是很迷人,而且可能真的很乏味 - 但是你在上线之前发现它会好得多!
答案 1 :(得分:0)
使用New Relic来确定瓶颈所在。请参阅我的演讲中的概述和识别瓶颈的讨论:
http://lanyrd.com/2012/pycon/spcdg/
同时编辑您的原始问题并添加您正在使用的mod_wsgi配置,以及您是否使用Apache prefork或worker MPM,因为您可能会在那里做一些非优化的事情。