如何用mod_wsgi提高Apache的性能?

问题描述 投票:1回答:2

使用Apache / 2.4.12(Unix)和mod_wsgi-4.4.11并打击apache / conf / extra的配置:

//httpd-mpm.conf
<IfModule mpm_worker_module>
    StartServers             3
    MinSpareThreads          75
    MaxSpareThreads          250 
    ThreadsPerChild          25
    MaxRequestWorkers        400
    MaxConnectionsPerChild   0
</IfModule>


//httpd-vhosts.conf
WSGIRestrictEmbedded On
<VirtualHost *:443>
    ServerName form.xxx.com

    WSGIScriptAlias / /usr/local/apache/services/form/form.wsgi 
    WSGIDaemonProcess paymentform user=test processes=10 threads=5 display-name=%{GROUP} maximum-requests=100

    WSGIApplicationGroup %{RESOURCE}
    WSGIProcessGroup form
    DocumentRoot /usr/local/apache/services/form

    SSLEngine On
    //any certification files  
   <Directory /usr/local/apache/services/form>
      Require all granted
   </Directory>
</VirtualHost>

在这个配置中,我使用Apache jmeter进行测试。

GET : form.xxx.com //only return "index" string
Number of Threads(users):100  
Ramp-up Period : 0
Loop count : 10 

但结果是......

samples: 1000
Average: 3069   
Min    : 13
Max    : 22426  
Std.Dev: 6671.693614549157
Error %: 10.0% 
Throughput : 24.1/sec
KB/sec : 10.06/sec
AvgBytes : 428.5

在测试期间,提高连接拒绝或连接超时并停止接收400~500个请求中的请求。服务器CPU或内存未满。

如何提高性能?修复mpm worker配置?或修复httpd-vhosts中的WSGI配置?

我修改下面的httpd-mpm.conf,但没有区别。

<IfModule mpm_worker_module>
    StartServers             10
    ServerLimit              32
    MinSpareThreads          75
    MaxSpareThreads          250 
    ThreadsPerChild          25
    MaxRequestWorkers        800
    MaxConnectionsPerChild   0
</IfModule>
apache mod-wsgi
2个回答
9
投票

您的配置中有许多错误。一个可能是剪切和粘贴错误。另一个是潜在的安全问题。一个会严重影响性能。

首先是你有:

WSGIProcessGroup form

如果你真的想要,那么web请求甚至不会进入WSGI应用程序,并且应该返回500错误响应。如果它没有给出错误,那么您的请求将被委托给上面配置中甚至没有提到的mod_wsgi守护程序进程组。这都是因为WSGIProcessGroup的值与WSGIDaemonProcess指令指定的已定义守护进程组的名称不匹配。

你必须拥有的是:

WSGIProcessGroup paymentform

我怀疑当你把它粘贴到问题中时,你只是搞砸了配置。

授权的一个相关问题是你有:

WSGIApplicationGroup %{RESOURCE}

无论如何,这是默认值。通常永远不需要明确地设置它。如果只将一个WSGI应用程序委托给守护程序进程组,那么通常使用的是:

WSGIApplicationGroup %{GLOBAL}

此特定值强制使用每个进程的主Python解释器上下文,这避免了某些第三方扩展模块在子解释器上下文中无法正常工作的问题。

第二个问题是潜在的安全问题。你有:

DocumentRoot /usr/local/apache/services/form

使用WSGIScriptAlias指令时,无需将DocumentRoot设置为应用程序的WSGI脚本文件或源代码所在的父目录。

这样做的危险在于,如果WSGIScriptAlias被意外禁用或更改为子URL,则所有源代码都可以下载。

简而言之,让DocumentRoot默认为整个服务器的空默认目录,或者为VirtualHost创建一个空目录并将其设置为该目录。

最后一件事会对你的表现产生巨大影响的是maximum-requests选项使用WSGIDaemonProcess。除非您了解其含义并具有特定的临时需求,否则不应在生产系统中使用maximum-requests

将此值设置为较低值意味着每100个请求将终止并重新启动守护程序进程。在基准测试的大量请求下,您将不断重新启动应用程序进程。

这样做的结果是CPU负载增加,响应时间慢得多,由于所有时间都重新启动服务器而导致服务器过载,因此可能会出现很长的响应时间。

所以,你应该做的绝对首先是删除maximum-requests,你应该看到一些立即改善。

您还在Apache MPM设置中遇到进程重启问题。它不是主要的,因为它只会影响代理请求的Apache工作进程,但它也会导致额外的CPU使用,并且可能需要更多的工作进程。

我之前讨论过由于MPM设置导致的Apache进程流失问题:

您的基准测试的最后一个问题是,如果您的测试返回的是来自某个简单的hello world类型程序的'index'字符串,那么它与您的真实世界应用程序没有任何关系。

真正的应用程序通常不那么简单,WSGI应用程序中的时间将更多地归因于模板渲染,数据库访问等等。这意味着真实应用程序的性能配置文件将完全不同并改变您应该如何配置服务器。

换句话说,使用hello world程序进行测试会让您完全错误地了解如何正确配置服务器。您真的需要了解应用程序在正常流量负载下的真实性能配置文件,并从那里开始工作。也就是说,将服务器锤击到破坏点也是错误的并且不现实。

我最近在我的blog site博客上写了关于人们使用的典型hello world测试是如何错误的,并给出了一些特定测试的例子,这些测试显示了不同WSGI服务器和配置的性能如何明显不同。这样做的目的是表明你不能从一个简单的测试开始,你需要了解你的WSGI应用程序正在做什么。

在所有这些中,要真正真正了解正在发生的事情以及如何正确调整服务器,您需要使用内置于WSGI服务器中的性能监控解决方案,因此可以深入了解其工作方式的不同方面。因此需要调整哪些旋钮。博客文章也涵盖了这一点。


0
投票

我遇到了与ash84描述的类似问题,我使用jmeter测试性能,发现当jmeter线程数设置超过某个值(在我的情况下为50)时,错误%变为非零。

在我看了Graham Dumpleton的talk之后,我意识到这主要是因为没有足够的备用MPM线程为即将到来的突发jmeter请求提供服务。在这种情况下,即使MPM线程的数量稍后被捕获,一些jmeter请求也不会在开始时提供。

简而言之,将MinSpareThreads设置为更大的值可以解决我的问题,我将jmeter线程从50提高到100并获得0%的错误。

    MinSpareThreads          120
    MaxSpareThreads          150 
    MaxRequestWorkers        200

WSGIDaemonProcess进程的数量乘以WSGIDaemonProcess线程的数量不必大于jmeter线程的数量。但是您可能需要将它们设置为更高的值,以确保WSGIDaemonProcess能够足够快地处理请求。

© www.soinside.com 2019 - 2024. All rights reserved.