Apache/mod_wsgi进程意外死亡

Kes*_*115 5 apache mod-wsgi amazon-ec2 flask python-2.7

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


运行

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

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


Linux Server详细信息:
2个虚拟CPU和4GB RAM

OS(输出uname -a)
Linux的IP-172-31-63-211 3.14.44-32.39.amzn1.x86_64#1 SMP星期四06月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"  
Run Code Online (Sandbox Code Playgroud)

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"  
Run Code Online (Sandbox Code Playgroud)

Gra*_*ton 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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

它在没有匹配的情况下工作的唯一原因是您已经通过以下方式打开了对 Apache 的访问来托管该目录中的文件:

<Directory "/Users/kesiena/Dropbox (MIT)/Sites">
    Require all granted
</Directory>
Run Code Online (Sandbox Code Playgroud)

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

不要将您的应用程序代码粘贴在针对 列出的目录下DocumentRoot

顺便说一句,即使您的 WSGI 应用程序在守护进程模式下运行,Apache 仍然可以回收用于代理 mod_wsgi 请求的工作进程。因此,即使您运行时间很长的请求继续在 WSGI 应用程序进程中运行,但如果工作进程由于运行时间过长而在此期间被回收,那么它在开始发送响应时也可能会失败。

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