如何阻止 WSGI 挂起 apache
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1223927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to stop WSGI from hanging apache
提问by Paul Tarjan
I have django running through WSGI like this :
我让 django 像这样运行 WSGI:
<VirtualHost *:80>
WSGIScriptAlias / /home/ptarjan/django/django.wsgi
WSGIDaemonProcess ptarjan processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup ptarjan
Alias /media /home/ptarjan/django/mysite/media/
</VirtualHost>
But if in python I do :
但如果在 python 中我做:
def handler(request) :
data = urllib2.urlopen("http://example.com/really/unresponsive/url").read()
the whole apache server hangs and is unresponsive with this backtrace
整个 apache 服务器挂起并且对这个回溯没有响应
#0 0x00007ffe3602a570 in __read_nocancel () from /lib/libpthread.so.0
#1 0x00007ffe36251d1c in apr_file_read () from /usr/lib/libapr-1.so.0
#2 0x00007ffe364778b5 in ?? () from /usr/lib/libaprutil-1.so.0
#3 0x0000000000440ec2 in ?? ()
#4 0x00000000004412ae in ap_scan_script_header_err_core ()
#5 0x00007ffe2a2fe512 in ?? () from /usr/lib/apache2/modules/mod_wsgi.so
#6 0x00007ffe2a2f9bdd in ?? () from /usr/lib/apache2/modules/mod_wsgi.so
#7 0x000000000043b623 in ap_run_handler ()
#8 0x000000000043eb4f in ap_invoke_handler ()
#9 0x000000000044bbd8 in ap_process_request ()
#10 0x0000000000448cd8 in ?? ()
#11 0x0000000000442a13 in ap_run_process_connection ()
#12 0x000000000045017d in ?? ()
#13 0x00000000004504d4 in ?? ()
#14 0x00000000004510f6 in ap_mpm_run ()
#15 0x0000000000428425 in main ()
on Debian Apache 2.2.11-7.
在 Debian Apache 2.2.11-7 上。
Similarly, can we be protected against :
同样,我们是否可以免受以下侵害:
def handler(request) :
while (1) :
pass
In PHP, I would set time and memory limits.
在 PHP 中,我会设置时间和内存限制。
回答by Graham Dumpleton
It is not 'deadlock-timeout' you want as specified by another, that is for a very special purpose which will not help in this case.
它不是您想要的另一个人指定的“死锁超时”,这是出于非常特殊的目的,在这种情况下无济于事。
As far as trying to use mod_wsgi features, you instead want the 'inactivity-timeout' option for WSGIDaemonProcess directive.
至于尝试使用 mod_wsgi 功能,您需要 WSGIDaemonProcess 指令的“inactivity-timeout”选项。
Even then, this is not a complete solution. This is because the 'inactivity-timeout' option is specifically to detect whether all request processing by a daemon process has ceased, it is not a per request timeout. It only equates to a per request timeout if daemon processes are single threaded. As well as help to unstick a process, the option will also have side effect of restarting daemon process if no requests arrive at all in that time.
即便如此,这也不是一个完整的解决方案。这是因为 'inactivity-timeout' 选项专门用于检测守护进程的所有请求处理是否已停止,它不是每个请求超时。如果守护进程是单线程的,它只相当于每个请求超时。除了有助于取消进程,该选项还具有重新启动守护进程的副作用,如果在那段时间内根本没有请求到达。
In short, there is no way at mod_wsgi level to have per request timeouts, this is because there is no real way of interrupting a request, or thread, in Python.
简而言之,在 mod_wsgi 级别没有办法让每个请求超时,这是因为在 Python 中没有真正的方法来中断请求或线程。
What you really need to implement is a timeout on the HTTP request in your application code. Am not sure where it is up to and whether available already, but do a Google search for 'urllib2 socket timeout'.
您真正需要实现的是应用程序代码中 HTTP 请求的超时。我不确定它在哪里以及是否已经可用,但请在 Google 上搜索“urllib2 socket timeout”。
回答by nosklo
If I understand well the question, you want to protect apache from locking up when running some random scripts from people. Well, if you're running untrusted code, I think you have other things to worry about that are worst than apache.
如果我很好地理解了这个问题,那么您想保护 apache 在运行一些来自人们的随机脚本时不会被锁定。好吧,如果您正在运行不受信任的代码,我认为您还有其他比 apache 更糟糕的事情要担心。
That said, you can use some configuration directives to adjust a saferenvironment. These two below are very useful:
也就是说,您可以使用一些配置指令来调整更安全的环境。下面这两个非常有用:
WSGIApplicationGroup- Sets which application group WSGI application belongs to. It allows to separate settings for each user - All WSGI applications within the same application group will execute within the context of the same Python sub interpreter of the process handling the request.
WSGIDaemonProcess- Configures a distinct daemon process for running applications. The daemon processes can be run as a user different to that which the Apache child processes would normally be run as. This directive accepts a lot of useful options, I'll list some of them:
user=name | user=#uid,group=name | group=#gid:Defines the UNIX user and groupname name or numeric user uid or group gid of the user/group that the daemon processes should be run as.
stack-size=nnnThe amount of virtual memory in bytes to be allocated for the stack corresponding to each thread created by mod_wsgi in a daemon process.
deadlock-timeout=sssDefines the maximum number of seconds allowed to pass before the daemon process is shutdown and restarted after a potential deadlock on the Python GIL has been detected. The default is 300 seconds.
WSGIApplicationGroup- 设置 WSGI 应用程序所属的应用程序组。它允许为每个用户单独设置 - 同一应用程序组中的所有 WSGI 应用程序将在处理请求的进程的同一 Python 子解释器的上下文中执行。
WSGIDaemonProcess- 为运行应用程序配置一个独特的守护进程。守护进程可以作为不同于 Apache 子进程通常运行的用户的用户运行。该指令接受很多有用的选项,我将列出其中的一些:
user=name | user=#uid,group=name | group=#gid:定义 UNIX 用户和组名名称或数字用户 uid 或守护进程运行的用户/组的组 gid。
stack-size=nnn要为守护进程中 mod_wsgi 创建的每个线程对应的堆栈分配的虚拟内存量(以字节为单位)。
deadlock-timeout=sss定义在检测到 Python GIL 上的潜在死锁后,在守护进程关闭和重新启动之前允许经过的最大秒数。默认值为 300 秒。
You can read more about the configuration directives here.
您可以在此处阅读有关配置指令的更多信息。

