¿Diferentes versiones de Python bajo el mismo uwsgi Emperor?

9

Estoy ejecutando un Emperador uwsgi con varios Vassals que sirven a una aplicación Python específica de un virtualenv diferente. Como uwsgi se compiló con su propio intérprete de Python 2.7, intentar usar un virtualenv con Python 3 produce el siguiente error en vassal.log:

ImportError: No module named site

Creo que el origen de este error es que uwsgi está utilizando su intérprete de Python 2.7 incorporado, mientras que el directorio virtualenv en el que se ejecuta solo admite intérpretes de Python 3. De hecho, cuando uso otro uwsgi (simplemente instalándolo con pip install uwsgiel mismo virtualenv), el error desaparece. Sin embargo, me gustaría que un Emperador gobernara sobre varios virtualenvs diferentes, por lo que instalar un uwsgi separado en cada uno no es una opción.

De acuerdo con esta respuesta en Stackoverflow, la forma correcta de resolver esto es compilar uwsgi con diferentes intérpretes de Python como módulos cargables. Antes de comprometerme con este enfoque, me gustaría saber cómo puedo configurar mis Vassals para que cada uno use otro complemento de intérprete.

En este momento tengo un Emperador que se inicia desde mi /etc/rc.local con la siguiente configuración:

[uwsgi]
uid = www-data
gid = www-data
master = true
emperor = /etc/uwsgi/vassals
daemonize = /var/log/uwsgi/emperor.log

Luego tengo un montón de Vassals con archivos ini como este:

[uwsgi]
master = false
single-interpreter = true
socket = /tmp/%n.sock
virtualenv = /home/user/.virtualenvs/djangoproject
chdir = /home/user/djangoproject
wsgi-file = project/wsgi.py
logto = /var/log/uwsgi/%n.log

No tengo problemas para compilar una versión ajustada de uwsgi con varios complementos de intérprete, pero me gustaría saber qué tengo que cambiar en mi configuración para usar estos intérpretes por separado. ¿Puedo decir un solo vassal.ini:

plugin = python3.4

y en otro:

plugin = python2.7

?

Por favor, ayúdame a descubrir cómo combinar Python 2.7 y Python 3 virtualenvs bajo el mismo uwsgi Emperor.

hedgie
fuente
puedes seguir este párrafo: uwsgi-docs.readthedocs.org/en/latest/…
roberto
Esto fue útil para construir un plugin de Python 3.6 para uwsgi, paulox.net/2017/04/04/how-to-use-uwsgi-with-python3-6-in-ubuntu Pude especificar qué versión usar en cada vasallo dependiendo de la versión que desee plugins=python3oplugins=python36
Dfranc3373

Respuestas:

9

Bueno, como no estaba exactamente abrumado por las respuestas, aquí está la solución que se me ocurrió:

Primero, creé un nuevo virtualenv con un intérprete de Python 3:

mkvirtualenv -p /usr/bin/python3 python3env

Luego instalé el stock uwsgi de Pypi, que se compila automáticamente con un intérprete de Python 3:

pip install uwsgi

/etc/uwsgi-python3Creé un directorio de configuración que contiene el emperor.ini y un subdirectorio vasallos, que contiene vassal.ini. Finalmente, agregué la siguiente línea a/etc/rc.local

/home/user/.virtualenvs/python3env/bin/uwsgi --ini /etc/uwsgi-python3/emperor.ini

Ahora hay un emperador uwsgi corriendo que usa el intérprete Python 3 para sus vasallos. No interfiere con otro uwsgi Emperor que ya se estaba ejecutando y usa el intérprete Python 2.7.

Sé que no es óptimo, porque no estoy usando la arquitectura de intérprete conectable que se explica en la documentación (¡gracias Roberto! No sé cómo podría haberlo pasado por alto). Sin embargo, funciona sin problemas y no tuve que tocar mi instalación uwsgi existente que sirve a un montón de aplicaciones de producción.

hedgie
fuente
Después de luchar con una uwsgiinstalación global , seguí este enfoque. Nice ... +1
nicorellius
@hedgie: eres un dios! Sé que no debería haber ningún comentario con solo un "¡Gracias!" (ya votado), pero te lo mereces. El enlace para construir los complementos únicos de Python no funcionó para mí en mi Ubuntu localizado, pero comenzar el uwsgi instalado en el entorno virtual se ejecuta con la versión correcta de Python ( ./venv/bin/uwsgi --python-version). ¡Perfecto!
taffit
Tengo el mismo problema con virtualenv en py 2.7.14 y uwsgi instalado globalmente en py 2.7.5. Obteniendo el error del sitio de importación a pesar de que todavía es todo Python 2.7
radtek
3

Bajo osx hice así. Desinstalé todos los uwsgi en mi sistema (de brew from pip, etc.).

Después de eso descargué bajo / usr / local el código fuente

wget https://projects.unbit.it/downloads/uwsgi-latest.tar.gz
tar zxvf uwsgi-latest.tar.gz

después

cd uwsgi-2.0.17
make PROFILE=nolang

De esta manera, creé un ejecutable sin complementos para Python.

Después de eso hice cada complemento para cada versión en mi sistema:

PYTHON=python3.6 ./uwsgi --build-plugin "plugins/python python36"
PYTHON=python2.7 ./uwsgi --build-plugin "plugins/python python27"
PYTHON=python2.6 ./uwsgi --build-plugin "plugins/python python26"

Ahora tengo 3 complementos.

En mis archivos ini para el emperador, especifiqué el directorio de complementos y la versión del complemento para cada archivo

[uwsgi]
plugins-dir = /usr/local/uwsgi-2.0.17
plugin = python36

[uwsgi]
plugins-dir = /usr/local/uwsgi-2.0.17
plugin = python27

[uwsgi]
plugins-dir = /usr/local/uwsgi-2.0.17
plugin = python26

...

Hice un enlace simbólico del binario uwsgi en mi carpeta / usr / local

ln -s /usr/local/uwsgi-2.0.17/uwsgi /usr/local/bin/uwsgi

Y después de correr el emperador

uwsgi --emperor /PATH/TO/INI/FILES/FOLDER/

Y voila ahora puedo ejecutar el proyecto python26, python27 y python36 simultáneamente

Giovanni Brescia
fuente
Hay muchas soluciones en torno, pero éste realmente resolvieron el problema que tuve funcionando uwsgiconpython 3.6
Evhz
0

Otra posible solución es reutilizar el "emperador" de todo el sistema, y ​​solo sustituir el vasallo con la nueva versión. De esta manera, no necesita inventar ninguna carpeta nueva /etcni iniciar nuevos servicios rc.local.

  1. Instalar a uwsgitravés de pipun virtualenv.
  2. Edite lo /etc/uwsgi/apps-enabled/your-app.inisiguiente:

    • Elimine la plugins=...línea (porque pip-compiled uwsgino admite complementos).
    • Agrega la línea:

      unprivileged-binary-patch = /path/to/your/venv/bin/uwsgi
      

      Esto obligará al emperador uWSGI a lanzar su propio uwsgibinario como vasallo.

  3. Recargue su aplicación en el emperador service uwsgi restart your-app.

El último paso por qué informa un error al reiniciar el servidor:

 * Starting app server(s) uwsgi
   ...fail!

Sin embargo, en realidad, el nuevo vasallo comienza bien, así como todas las demás aplicaciones. No encontré el tiempo para depurar esto.

KT.
fuente