uWSGI在pre​​forking +线程模式下定义多个安装点时引发段错误

我正在主持一个由多个Python模块组成的应用程序。 到目前为止,我们在MPM工作模式下使用Apache,在工作环境下使用mod_wsgi。

现在我们要检查一下nginx + uwsgi可能是一个更高性能的环境。 Python是Python 2.6.6,uwsgi是2.0.7。 我有我的应用程序(减less的例子)下面的uWSGIconfiguration:

[uwsgi] chdir = /path/to/app chmod-socket = 777 no-default-app = True socket = /tmp/socket.sock master = 1 processes = 4 threads = 2 enable-threads = true touch-reload=/root/uwsgi.ini manage-script-name = True mount = /accounts=account.py [... several more mount directives ...] mount = /ping=ping.py [... several more mount directives ...] mount = /subscriptions=subscription.py callable = application enable-logging = 1 plugin = /usr/lib/uwsgi/stats_pusher_statsd stats-push = statsd:graphite-int.cern.ch:8125:uwsgi-test enable-metrics = 1 memory-report = 1 stats = /tmp/stats.sock 

当我像这样开始uWSGI的时候,起初一切看起来都不错:

 [uWSGI] getting INI configuration from rucio.wsgi.ini *** Starting uWSGI 2.0.7 (64bit) on [Mon Aug 25 19:15:07 2014] *** compiled with version: 4.4.7 20120313 (Red Hat 4.4.7-4) on 22 August 2014 22:51:22 os: Linux-2.6.32-431.3.1.el6.x86_64 #1 SMP Mon Jan 6 11:34:51 CET 2014 nodename: rucio-server-dev-ngnix machine: x86_64 clock source: unix detected number of CPU cores: 4 current working directory: /root detected binary path: /usr/bin/uwsgi !!! no internal routing support, rebuild with pcre support !!! uWSGI running as root, you can use --uid/--gid/--chroot options *** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** your processes number limit is 63837 your memory page size is 4096 bytes detected max file descriptor number: 4096 lock engine: pthread robust mutexes thunder lock: disabled (you can enable it with --thunder-lock) uwsgi socket 0 inherited UNIX address /tmp/rucio.sock fd 3 Python version: 2.6.6 (r266:84292, Jan 23 2014, 10:39:35) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] Python main interpreter initialized at 0x26b1c00 python threads support enabled your server socket listen backlog is limited to 100 connections your mercy for graceful operations on workers is 60 seconds mapped 415360 bytes (405 KB) for 8 cores *** Operational MODE: preforking+threaded *** initialized 108 metrics mounting account.py on /accounts WSGI app 0 (mountpoint='/accounts') ready in 1 seconds on interpreter 0x26b1c00 pid: 2839 [... several more mount outputs like the one above ...] mounting ping.py on /ping WSGI app 8 (mountpoint='/ping') ready in 2 seconds on interpreter 0x9b020b0 pid: 2839 [... several more mount outputs like the one above ...] mounting trace.py on /traces WSGI app 15 (mountpoint='/traces') ready in 2 seconds on interpreter 0xf393210 pid: 2839 *** uWSGI is running in multiple interpreter mode *** gracefully (RE)spawned uWSGI master process (pid: 2839) spawned uWSGI worker 1 (pid: 2986, cores: 2) spawned uWSGI worker 2 (pid: 2988, cores: 2) spawned uWSGI worker 3 (pid: 2990, cores: 2) spawned uWSGI worker 4 (pid: 2992, cores: 2) metrics collector thread started *** Stats server enabled on /tmp/rucio-stats.sock fd: 16 *** 

但是,一旦第一个请求进入,独立于请求的挂载点,我会得到以下回溯(例如GET / ping):

 !!! uWSGI process 2988 got Segmentation Fault !!! *** backtrace of 2988 *** /usr/bin/uwsgi(uwsgi_backtrace+0x29) [0x46c8d9] /usr/bin/uwsgi(uwsgi_segfault+0x21) [0x46ca61] /lib64/libc.so.6() [0x38bf8329a0] /usr/lib64/libpython2.6.so.1.0(PyObject_Call+0x3a) [0x38c2c43c4a] /usr/lib64/libpython2.6.so.1.0(PyEval_CallObjectWithKeywords+0x43) [0x38c2ccfc93] /usr/bin/uwsgi(python_call+0x1f) [0x47a0bf] /usr/bin/uwsgi(uwsgi_request_wsgi+0x132) [0x47c602] /usr/bin/uwsgi(wsgi_req_recv+0x92) [0x420352] /usr/bin/uwsgi(simple_loop_run+0xc5) [0x464265] /usr/bin/uwsgi(uwsgi_ignition+0x254) [0x468074] /usr/bin/uwsgi(uwsgi_worker_run+0x330) [0x468400] /usr/bin/uwsgi(uwsgi_run+0x3e5) [0x468865] /lib64/libc.so.6(__libc_start_main+0xfd) [0x38bf81ed1d] /usr/bin/uwsgi() [0x41d189] *** end of backtrace *** DAMN ! worker 2 (pid: 2988) died :( trying respawn ... Respawned uWSGI worker 2 (new pid: 3003) 

我猜是最有趣的部分是,如果我删除所有其他挂载点,例如只保留

 mount = /ping=ping.py 

一切按预期工作。 为了确保这个错误与我们的应用程序无关,我也尝试了uWSGI站点上提供的“Hello World”示例。 但行为保持不变。 一个挂载点工作正常,不止一个导致此段错误。

此外,只要我删除线程设置线程= 2 (不是线程启用!)它也适用于多个挂载点。 因此,我怀疑这个错误实际上只限于在multithreading模式下有多个挂载点。 请记住,它在Apache MPM工作模式下工作,所以我不希望应用程序是原因(至less在这种情况下:D)

如果只有Apache能够multithreading,那么我们真的很想把这个问题弄清楚,因为如果Apache节点和nginx / uwsgi节点之间的比较不是公平的,那么对吧?

如果你需要更多的信息,请让我知道,并乐意提供。 感谢您的任何提示或想法,只是为了阅读这个你已经是一个每天的论坛英雄;-)

干杯,拉尔夫

试试这个补丁

https://github.com/unbit/uwsgi/commit/e45f710694f18052aa00ee5bb866d9aeca76fb80#diff-d41d8cd98f00b204e9800998ecf8427e

但是在采取这种方法之前要三思。 在同一进程地址空间中有多个应用程序可能看起来很酷,但不久后您将付出不理想的实现(当在CPython中使用多个解释器使用多个线程时,太多的案例和解决方法)

如果在mod_wsgi中运行良好,很可能也会与uWSGI一起工作,但是考虑在专用进程中拆分每个安装点。