Sites Python Django no Apache + mod_wsgi com proxy nginx: desempenho altamente flutuante

Sites Python Django no Apache + mod_wsgi com proxy nginx: desempenho altamente flutuante

Eu tenho uma caixa Ubuntu 10.04 executando várias dezenas de sites Python Django usando mod_wsgi (modo incorporado; omodo mais rápido, se configurado corretamente). O desempenho varia muito. Às vezes rápido, às vezes com atraso de vários segundos. Os gráficos sobre fumo estão por toda parte.

Recentemente, também adicionei um proxy nginx para o conteúdo estático, na esperança de que isso curasse o desempenho altamente flutuante. Mas, embora tenha reduzido significativamente o número de solicitações que o Apache precisa processar, não ajudou no problema principal.

Ao clicar em sites enquanto executa o htop, pode-se perceber que às vezes as solicitações são quase instantâneas, enquanto às vezes faz com que o Apache consuma 100% da CPU por alguns segundos. Eu realmente não entendo de onde vem essa flutuação.

Eu configurei o mpm_worker para Apache assim:

StartServers          1
MinSpareThreads      50
MaxSpareThreads      50
ThreadLimit          64
ThreadsPerChild      50
MaxClients           50
ServerLimit          1
MaxRequestsPerChild  0
MaxMemFree           2048

1 servidor com 50 threads, máximo de 50 clientes. Munin e apache2ctl -tambos mostram uma presença consistente de trabalhadores; eles não são destruídos e criados o tempo todo. No entanto, ele se comporta como tal.

Esseme diz que uma vez criado um subinterpretador, ele deve permanecer na memória, mas parece que os sites precisam ser recarregados o tempo todo.

Eu também tenho uma caixa nginx+gunicorn, que funciona muito bem. Eu realmente gostaria de saber por que o Apache é tão aleatório.

Esta é uma configuração de host virtual:

<VirtualHost *:81>
    ServerAdmin [email protected]
    ServerName example.com

    DocumentRoot /srv/http/site/bla

    Alias /static/ /srv/http/site/static
    Alias /media/ /srv/http/site/media
    WSGIScriptAlias / /srv/http/site/passenger_wsgi.py

    <Directory />
            AllowOverride None
    </Directory>

    <Directory /srv/http/site>
            Options -Indexes FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            allow from all
    </Directory>

  • Ubuntu 10.04
  • Apache 2.2.14
  • mod_wsgi 2.8
  • nginx 0.7.65

Editar: coloquei um código no arquivo settings.py de um site que grava a data em um arquivo tmp sempre que ele é carregado. Agora posso ver que o site não é recarregado aleatoriamente o tempo todo, então o Apache deve mantê-lo na memória. Então, isso é bom, exceto que não me aproxima de uma resposta...

Editar: acabei de encontrar um erro que também pode estar relacionado a isso:

  File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
    errread, errwrite)

  File "/usr/lib/python2.6/subprocess.py", line 1049, in _execute_child
    self.pid = os.fork()

OSError: [Errno 12] Cannot allocate memory

O servidor tem 600 de 2.000 MB livres, o que deve ser suficiente. Existe um limite definido no Apache ou WSGI em algum lugar?

Responder1

Você já tentou usar o New Relic para tentar identificar se isso é um problema em seu aplicativo da web? Nível gratuito disponível e também uma avaliação inicial completa. Visão geral do que isso pode oferecer:

Se um problema específico com o aplicativo da web do serviço de back-end usado não se destacar como um problema, o relatório de análise de capacidade do servidor WSGI poderá mostrar algo, pois informará se você está esgotando a capacidade. Ele também pode dizer se você está superprovisionado e desperdiçando recursos, o que na verdade é o caso com bastante frequência.

Aliás, em geral eu não recomendaria o uso de 50 threads de solicitação em um único processo. É melhor usar cerca de 5 threads e vários processos. Exatamente o que é melhor realmente depende do aplicativo específico, se ele está executando muito trabalho vinculado à CPU e quanto tem para lidar com solicitações de longa execução. O fornecimento de muitos arquivos estáticos por meio do mesmo Apache também pode impactar isso, com o modo daemon do mod_wsgi possivelmente sendo uma solução geral melhor.

Você também está em uma versão mod_wsgi muito antiga, embora não acredite que isso possa causar problemas.

Finalmente, para evitar problemas com alguns módulos de extensão C de terceiros para Python, se este for o único aplicativo WSGI naquele servidor, defina:

WSGIApplicationGroup %{GLOBAL}

Responder2

Eu consertei isso. Converti todos os sites de produção para usarem seus próprios processos (e todos os sites de desenvolvimento juntos em um processo também), no modo daemon. Os gráficos do Smokeping estão muito melhores agora. O desempenho é estável.

Isso ainda me deixa sem saber por que o modo incorporado teve esses problemas, porque até onde sei, não tive criação/destruição de processos, mas pelo menos tenho um servidor em melhor execução.

Editar:

Como exemplo em uma configuração de site Apache:

WSGIDaemonProcess mysite12 processes=1 threads=10 display-name=%{GROUP}
WSGIProcessGroup mysite12

E então, para sites de baixa prioridade, coloquei isto wsgi.conf:

WSGIDaemonProcess developmentsites processes=1 threads=15 display-name=%{GROUP}

E então em uma configuração do Apache:

WSGIProcessGroup developmentsites

Veja a diferença (também por causa do proxy nginx):

insira a descrição da imagem aqui

informação relacionada