1 votes

uWSGI soulève des erreurs de segmentation lors de la définition de plusieurs points de montage en mode preforking+threaded.

J'héberge une application composée de plusieurs modules Python. Jusqu'à présent, nous utilisons Apache en mode travailleur MPM et mod_wsgi, qui est un environnement de travail.

Nous voulons maintenant vérifier si nginx + uwsgi peuvent constituer un environnement plus performant. Python est Python 2.6.6 et uwsgi est 2.0.7. J'ai la configuration uWSGI suivante pour mon application (exemple réduit) :

[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

Lorsque je lance uWSGI de cette manière, tout me semble d'abord correct :

[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 ***

Mais dès que la première demande arrive, indépendamment du point de montage demandé, j'obtiens le Traceback suivant (l'exemple est un 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)

Ce qui est, je pense, la partie la plus intéressante, c'est que si je supprime tous les autres points de montage, et que je ne garde par exemple que

mount = /ping=ping.py

tout fonctionne comme prévu. Pour m'assurer que cette erreur n'est pas liée à notre application, j'ai également essayé l'exemple 'Hello World' fourni sur le site uWSGI. Mais le comportement est resté le même. Un point de montage fonctionne bien, mais plus d'un point de montage provoque cette erreur.

Aussi, dès que j'enlèverai le réglage des fils fils = 2 (pas le threads-enabled !) il fonctionne également bien avec des points de montage multiples. Je soupçonne donc que l'erreur est vraiment limitée à l'utilisation de plusieurs points de montage en mode multithread. Et gardez à l'esprit que cela fonctionne en mode travailleur Apache MPM, donc je ne pense pas que l'application soit la raison (du moins pas dans ce cas :D ).

J'aimerais vraiment résoudre ce problème, car la comparaison entre les nœuds Apache et les nœuds nginx/uwsgi ne serait pas juste si seul Apache est capable de faire du multithreading, non ?

Si vous avez besoin de plus d'informations, n'hésitez pas à me le faire savoir et je me ferai un plaisir de vous les fournir. Merci pour tous les conseils ou idées, et rien que pour avoir lu jusqu'ici, vous êtes déjà un héros du forum de tous les jours ;-)

A la vôtre, Ralph

0voto

roberto Points 1782

Essayez ce patch

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

mais réfléchissez-y à deux fois avant de suivre une telle approche. Avoir plusieurs applications dans le même espace d'adressage de processus peut sembler cool, mais tôt ou tard, vous paierez pour une mise en œuvre sous-optimale (trop de cas de figure et de solutions de contournement lors de l'utilisation de plusieurs threads avec plusieurs interprètes dans CPython).

Si cela a bien fonctionné avec mod_wsgi, cela fonctionnera très probablement aussi avec uWSGI, mais envisagez de séparer chaque point de montage dans un processus dédié.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X