Apache / mod_wsgi进程意外死亡

时间:2016-10-02 05:51:23

标签: apache python-2.7 amazon-ec2 flask mod-wsgi

我通过发出一个超过30分钟的请求来测试在Apache Web服务器上运行的Python Flask Web应用程序的限制。该请求需要数千个数据库请求(一个接一个)到MySQL数据库。我理解这应该在apache服务器之外作为一个单独的异步进程运行,但是现在让我们忽略它。我遇到的问题是,虽然当我在我的Mac上测试它时完全运行,但它在Linux服务器(AWS EC2上的Amazon linux)上运行时会突然死亡。我还没弄清楚到底是什么杀了它。我检查过服务器内存不足。该过程使用非常少的RAM。我找不到任何Apache配置参数或任何对我有意义的错误消息(即使在将apache logLevel设置为debug之后)。请到哪里查看我需要帮助。这里有关于我的设置的更多详细信息:

运行时间

服务器: 8分钟,27分钟,21分钟后死亡分别为22分钟。请注意,大多数这些运行都在UAT服务器上,这是服务器处理的唯一请求。

Mac:它在服务器上运行的速度要慢得多。该过程成功运行,耗时2小时47分钟。

Linux服务器详细信息:
2个虚拟CPU和4GB RAM

操作系统uname -a的输出)
Linux ip-172-31-63-211 3.14.44-32.39.amzn1.x86_64#1 SMP Thu Jun 11 20:33:38 UTC 2015 x86_64 x86_64 x86_64 GNU / Linux

Apache error_log: https://drive.google.com/file/d/0B3XXZfJyzJYsNkFDU3hJekRRUlU/view?usp=sharing

Apache配置文件: https://drive.google.com/file/d/0B3XXZfJyzJYsM2lhSmxfVVRNNjQ/view?usp=sharing

Apache版apachectl -V的输出)

Server version: Apache/2.4.23 (Amazon)  
Server built:   Jul 29 2016 21:42:17  
Server's Module Magic Number: 20120211:61  
Server loaded:  APR 1.5.1, APR-UTIL 1.4.1  
Compiled using: APR 1.5.1, APR-UTIL 1.4.1  
Architecture:   64-bit  
Server MPM:     prefork  
  threaded:     no  
    forked:     yes (variable process count)  
Server compiled with....  
 -D APR_HAS_SENDFILE  
 -D APR_HAS_MMAP  
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)  
 -D APR_USE_SYSVSEM_SERIALIZE  
 -D APR_USE_PTHREAD_SERIALIZE  
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT  
 -D APR_HAS_OTHER_CHILD  
 -D AP_HAVE_RELIABLE_PIPED_LOGS  
 -D DYNAMIC_MODULE_LIMIT=256  
 -D HTTPD_ROOT="/etc/httpd"  
 -D SUEXEC_BIN="/usr/sbin/suexec"  
 -D DEFAULT_PIDLOG="/var/run/httpd/httpd.pid"  
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"  
 -D DEFAULT_ERRORLOG="logs/error_log"  
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"  
 -D SERVER_CONFIG_FILE="conf/httpd.conf"  

Mac详细信息:

Apache配置文件: https://drive.google.com/file/d/0B3XXZfJyzJYsRUd6NW5NY3lON1U/view?usp=sharing

Apache版apachectl -V的输出)

Server version: Apache/2.4.18 (Unix)  
Server built:   Feb 20 2016 20:03:19  
Server's Module Magic Number: 20120211:52  
Server loaded:  APR 1.4.8, APR-UTIL 1.5.2  
Compiled using: APR 1.4.8, APR-UTIL 1.5.2  
Architecture:   64-bit  
Server MPM:     prefork  
  threaded:     no  
    forked:     yes (variable process count)  
Server compiled with....  
 -D APR_HAS_SENDFILE  
 -D APR_HAS_MMAP  
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)  
 -D APR_USE_FLOCK_SERIALIZE  
 -D APR_USE_PTHREAD_SERIALIZE  
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT  
 -D APR_HAS_OTHER_CHILD  
 -D AP_HAVE_RELIABLE_PIPED_LOGS  
 -D DYNAMIC_MODULE_LIMIT=256  
 -D HTTPD_ROOT="/usr"  
 -D SUEXEC_BIN="/usr/bin/suexec"  
 -D DEFAULT_PIDLOG="/private/var/run/httpd.pid"  
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"  
 -D DEFAULT_ERRORLOG="logs/error_log"  
 -D AP_TYPES_CONFIG_FILE="/private/etc/apache2/mime.types"  
 -D SERVER_CONFIG_FILE="/private/etc/apache2/httpd.conf"  

3 个答案:

答案 0 :(得分:2)

如果您使用的是mod_wsgi的嵌入模式,可以在Apache控制进程的生命周期时发生,如果它认为由于流量不足而不再需要进程,则可以回收它们。

你可能在考虑,但我使用的是守护进程模式而不是嵌入式模式,但实际情况是你的配置错误。你有:

<VirtualHost *:5010>
    ServerName localhost

    WSGIDaemonProcess entry user=kesiena group=staff threads=5
    WSGIScriptAlias "/" "/Users/kesiena/Dropbox (MIT)/Sites/onetext/onetext.local.wsgi"

    <directory "/Users/kesiena/Dropbox (MIT)/Sites/onetext/app">
        WSGIProcessGroup start
        WSGIApplicationGroup %{GLOBAL}
        WSGIScriptReloading On
        Order deny,allow
        Allow from all
    </directory>
</virtualhost>

Directory块没有使用与WSGIScriptAlias中的路径匹配的目录,因此不适用。

使用:

<VirtualHost *:5010>
    ServerName localhost

    WSGIDaemonProcess entry user=kesiena group=staff threads=5
    WSGIScriptAlias "/" "/Users/kesiena/Dropbox (MIT)/Sites/onetext/onetext.local.wsgi"

    <directory "/Users/kesiena/Dropbox (MIT)/Sites/onetext">
        WSGIProcessGroup start
        WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all
    </directory>
</virtualhost>

它完全没有匹配的唯一原因是你通过以下方式打开了访问Apache以访问该目录中文件的权限:

<Directory "/Users/kesiena/Dropbox (MIT)/Sites">
    Require all granted
</Directory>

DocumentRoot设置为应用程序源代码所在位置的父目录也是不好的做法。按照它的编写方式,我可能会遇到不同的端口或VirtualHost并下载所有应用程序代码的风险。

请勿将您的应用程序代码粘贴在DocumentRoot列出的目录下。

顺便说一下,即使你有以守护进程模式运行的WSGI应用程序,Apache仍然可以回收它将用于代理对mod_wsgi的请求的工作进程。因此,即使您的长时间运行请求在WSGI应用程序进程中继续运行,如果工作进程在过渡期间被回收,因为它已经运行了太长时间,它一旦开始发送响应就会失败。

你绝对应该将长时间运行的操作分配给后端Celery任务队列或类似的。

答案 1 :(得分:1)

你可能会遇到强制套接字关闭,尽管你给出的时间看起来不太可能。对于我在Azure上的项目,任何闲置约3分钟的连接都将被系统关闭。我相信这些闭包是在网络路由中的服务器之前完成的,因此无法禁用它们或增加超时。

答案 2 :(得分:0)

这是一个棘手的问题。

猜猜1:我曾经遇到过类似的问题。你有没有玩过KeepAlive时间?将其设置为60分钟或更长时间并测试以查看问题是否仍然存在。更多细节https://httpd.apache.org/docs/2.4/de/mod/core.html

猜猜2:亚马逊能否在后台“移动”您的机器,这会中断您的数据库连接或烧瓶无法处理VM的“卸载”和“加载”?