Diferentes versões do Python sob o mesmo imperador uwsgi?

6

Eu estou executando um Emperor uwsgi com vários Vassals, cada um servindo um aplicativo Python específico de um virtualenv diferente. Como o uwsgi foi compilado com seu próprio interpretador Python 2.7, tentar usar um virtualenv com o Python 3 produz o seguinte erro em vassal.log:

ImportError: No module named site

Acredito que a origem desse erro é que o uwsgi está usando o interpretador interno do Python 2.7, enquanto o diretório virtualenv em execução apenas suporta intérpretes do Python 3. De fato, quando eu uso outro uwsgi (simplesmente instalando-o com pip install uwsgi no mesmo virtualenv), o erro desaparece. No entanto, eu gostaria que um Imperador governasse vários virtualenvs diferentes, então instalar um uwsgi separado em cada um deles não é uma opção.

De acordo com esta resposta no Stackoverflow, o jeito certo de resolver isso é compilar o uwsgi com diferentes interpretadores Python como módulos carregáveis. Antes de me comprometer com essa abordagem, gostaria de saber como posso configurar meus Vassalos para que cada um use outro plugin de intérprete.

Neste momento, tenho um Emperor que é iniciado a partir do meu /etc/rc.local com as seguintes configurações:

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

Então eu tenho um monte de Vassals com arquivos 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

Eu não tenho nenhum problema em compilar uma versão do uwsgi com vários plugins de interpretador, mas eu gostaria de saber o que eu tenho que mudar na minha configuração para usar esses interpretadores separados. Posso apenas dizer um vassal.ini:

plugin = python3.4

e em outro:

plugin = python2.7

?

Por favor, ajude-me a descobrir como combinar os virtualenvs do Python 2.7 e do Python 3 com o mesmo imperador uwsgi.

    
por hedgie 03.10.2014 / 23:02

3 respostas

6

Bem, como não fiquei impressionado com as respostas, aqui está a solução que eu mesmo criei:

Primeiro, criei um novo virtualenv com um interpretador do Python 3:

mkvirtualenv -p /usr/bin/python3 python3env

Então eu instalei o arquivo uwsgi do Pypi, que é compilado automaticamente com um interpretador do Python 3:

pip install uwsgi

Eu criei um diretório de configuração /etc/uwsgi-python3 que contém o emperor.ini e um subdiretório vassals, contendo vassal.ini. Por fim, adicionei a seguinte linha a /etc/rc.local

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

Agora existe um imperador uwsgi que usa o interpretador Python 3 para seus vassalos. Não interfere com outro Imperador do uwsgi que já estava rodando e usa o interpretador Python 2.7.

Eu sei que não é ideal, porque não estou usando a arquitetura de intérprete conectável que é explicado na documentação (obrigado roberto! Eu não sei como eu poderia ter esquecido isso). No entanto, ele funciona perfeitamente e eu não tive que tocar na minha instalação existente do uwsgi que está servindo um monte de aplicativos de produção.

    
por 05.10.2014 / 10:20
1

Sob osx eu fiz assim. Eu instalei todos os uwsgi no meu sistema (da infusão de pip, etc.).

Depois disso eu baixei em / usr / local o código fonte

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

depois

cd uwsgi-2.0.17
make PROFILE=nolang

Desta forma eu criei um executável sem plugins para python.

Depois disso, fiz cada plug-in para cada versão no meu 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"

Agora eu tenho 3 plugins.

Nos meus arquivos ini para o emperor eu especifiquei o diretório de plugins e a versão do plugin para cada arquivo

[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

...

Eu criei um link simbólico para o binário uwsgi na minha pasta / usr / local

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

E depois de correr o imperador

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

E agora eu posso executar projetos python26, python27 e python36 simultaneamente

    
por 15.06.2018 / 08:46
0

Outra solução possível é reutilizar o "imperador" de todo o sistema e apenas substituir o vassalo pela nova versão. Dessa forma, você não precisa inventar nenhuma nova pasta em /etc nem lançar novos serviços para rc.local .

  1. Instale uwsgi via pip em um virtualenv.
  2. Edite o /etc/uwsgi/apps-enabled/your-app.ini da seguinte forma:

    • Remova a linha plugins=... (porque o uwsgi compilado por pip não suporta plug-ins).
    • Adicione a linha:

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

      Isso forçará o imperador uWSGI a lançar seu próprio binário uwsgi como o vassalo.

  3. Atualize seu aplicativo no emperor service uwsgi restart your-app .

O último passo informa uma falha ao reiniciar o servidor:

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

No entanto, na realidade, o novo vassalo começa bem, assim como todos os outros aplicativos. Eu não encontrei tempo para depurar isso.

    
por 17.01.2018 / 13:00