Différentes versions de Python sous le même empereur uwsgi?

9

J'exécute un empereur uwsgi avec divers vassaux qui servent chacun une application Python spécifique à partir d'un virtualenv différent. Puisque uwsgi a été compilé avec son propre interpréteur Python 2.7, essayer d'utiliser un virtualenv avec Python 3 dans celui-ci produit l'erreur suivante dans vassal.log:

ImportError: No module named site

Je crois que l'origine de cette erreur est que uwsgi utilise son interpréteur Python 2.7 intégré, tandis que le répertoire virtualenv dans lequel il s'exécute ne prend en charge que les interprètes Python 3. En effet, lorsque j'utilise un autre uwsgi (simplement en l'installant avec pip install uwsgidans le même virtualenv), l'erreur disparaît. Cependant, j'aimerais qu'un empereur règne sur plusieurs virtualenv différents, donc installer un uwsgi séparé dans chacun n'est pas une option.

Selon cette réponse sur Stackoverflow, la bonne façon de résoudre ce problème consiste à compiler uwsgi avec différents interprètes Python sous forme de modules chargeables. Avant de m'engager dans cette approche, j'aimerais savoir comment je peux configurer mes Vassals pour utiliser chacun un autre plugin d'interpréteur.

En ce moment, j'ai un empereur qui est démarré à partir de mon /etc/rc.local avec les paramètres suivants:

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

Ensuite, j'ai un tas de Vassaux avec des fichiers ini comme celui-ci:

[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

Je n'ai aucun problème à compiler une version modifiée de uwsgi avec plusieurs plugins d'interpréteur, mais j'aimerais savoir ce que je dois changer dans ma configuration pour utiliser réellement ces interprètes séparés. Puis-je simplement dire un vassal.ini:

plugin = python3.4

et dans un autre:

plugin = python2.7

?

S'il vous plaît, aidez-moi à comprendre comment combiner Python 2.7 et Python 3 virtualenvs sous le même empereur uwsgi.

hedgie
la source
vous pouvez suivre ce paragraphe: uwsgi-docs.readthedocs.org/en/latest/…
roberto
Cela a été utile pour construire un plugin python 3.6 pour uwsgi, paulox.net/2017/04/04/how-to-use-uwsgi-with-python3-6-in-ubuntu J'ai pu spécifier la version à utiliser dans chaque vassal selon la version que vous voulez plugins=python3ouplugins=python36
Dfranc3373

Réponses:

9

Eh bien, comme je n'ai pas été exactement submergé par les réponses, voici la solution que j'ai trouvée moi-même:

Tout d'abord, j'ai créé un nouveau virtualenv avec un interpréteur Python 3:

mkvirtualenv -p /usr/bin/python3 python3env

J'ai ensuite installé le stock uwsgi de Pypi, qui se compile automatiquement avec un interpréteur Python 3:

pip install uwsgi

J'ai créé un répertoire de configuration /etc/uwsgi-python3qui contient emperor.ini et un sous-répertoire vassals, contenant vassal.ini. Enfin, j'ai ajouté la ligne suivante à/etc/rc.local

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

Maintenant, il y a un uwsgi Emperor qui utilise l'interpréteur Python 3 pour ses vassaux. Il n'interfère pas avec un autre Empereur uwsgi qui était déjà en cours d'exécution et utilise l'interpréteur Python 2.7.

Je sais que ce n'est pas optimal, car je n'utilise pas l'architecture d'interpréteur enfichable qui est expliquée dans la documentation (merci roberto! Je ne sais pas comment j'aurais pu ignorer cela). Cependant, il fonctionne parfaitement et je n'ai pas eu à toucher à mon installation uwsgi existante qui sert un tas d'applications de production.

hedgie
la source
Après avoir lutté avec une uwsgiinstallation globale , j'ai opté pour cette approche. Nice ... +1
nicorellius
@hedgie: tu es un dieu! Je sais qu'il ne devrait pas y avoir de commentaires avec juste un "Merci!" (déjà voté), mais vous le méritez. Le lien pour la construction des plugins Python uniques ne fonctionnait pas pour moi sur mon Ubuntu localisé, mais le démarrage de l'uwsgi installé dans l'environnement virtuel s'exécute avec la bonne version de python ( ./venv/bin/uwsgi --python-version). Parfait!
taffit
J'ai le même problème avec virtualenv sur py 2.7.14 et uwsgi installé globalement sur py 2.7.5. Obtenir l'erreur du site d'importation même si c'est toujours tout python 2.7
radtek
3

Sous osx j'ai fait comme ça. J'ai désinstallé tous les uwsgi sur mon système (de l'infusion du pip, etc.).

Après cela, j'ai téléchargé sous / usr / local le code source

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

après

cd uwsgi-2.0.17
make PROFILE=nolang

De cette façon, j'ai créé un exécutable sans plugins pour python.

Après cela, j'ai créé chaque plugin pour chaque version de mon système:

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"

Maintenant, j'ai 3 plugins.

Dans mes fichiers ini pour l'empereur, j'ai spécifié le répertoire des plugins et la version du plugin pour chaque fichier

[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

...

J'ai créé un lien symbolique vers le binaire uwsgi dans mon dossier / usr / local

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

Et après avoir couru l'empereur

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

Et voila maintenant, je peux exécuter le projet python26, python27 et python36 simultanément

Giovanni Brescia
la source
Il existe de nombreuses solutions, mais celle-ci a vraiment résolu le problème uwsgiavec python 3.6
lequel
0

Une autre solution possible consiste à réutiliser "l'empereur" à l'échelle du système et à ne remplacer le vassal que par la nouvelle version. De cette façon, vous n'avez pas besoin d'inventer de nouveaux dossiers /etcni de lancer de nouveaux services rc.local.

  1. Installez uwsgivia pipdans un virtualenv.
  2. Modifiez le /etc/uwsgi/apps-enabled/your-app.inicomme suit:

    • Supprimez la plugins=...ligne (car pip-compiled uwsgine prend pas en charge les plugins).
    • Ajoutez la ligne:

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

      Cela forcera l'empereur uWSGI à lancer votre propre uwsgibinaire en tant que vassal.

  3. Rechargez votre application dans l'empereur service uwsgi restart your-app.

La dernière étape signale un échec de redémarrage du serveur:

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

Cependant, en réalité, le nouveau vassal démarre bien ainsi que toutes les autres applications. Je n'ai pas trouvé le temps de déboguer cela.

KT.
la source