desempenho cgi Python
-
06-07-2019 - |
Pergunta
Eu tenho um aplicativo herdado python escrito como CGI. Até agora isso funciona OK, mas o número de usuários simultâneos será incrementado em grande parte no futuro muito próximo. Aqui no SO eu li: "CGI é ótimo para sites de baixo tráfego, mas tem alguns problemas de desempenho para qualquer outra coisa". Sei que teria sido melhor começar de outra maneira, mas CGI é o que é é agora.
Será que alguém ponto-me uma orientação sobre a forma de manter o CGI executar, sem ter que reescrever todo o código?
Solução
CGI não escala porque cada pedido bifurca um processo servidor novo. É um monte de sobrecarga. mod_wsgi evitar a sobrecarga por bifurcação um solicitações de processo e entregando para que um processo em execução.
Vamos supor que a aplicação é o pior tipo de cgi.
O pior caso é que ele tem arquivos como esta.
my_cgi.py
import cgi
print "status: 200 OK"
print "content-type: text/html"
print
print "<!doctype...>"
print "<html>"
etc.
Você pode tentar "envoltório" os arquivos CGI originais para torná-lo wsgi.
wsgi.py
import cStringIO
def my_cgi( environ, start_response ):
page = cStringIO.StringIO()
sys.stdout= page
os.environ.update( environ )
# you may have to do something like execfile( "my_cgi.py", globals=environ )
execfile( "my_cgi.py" )
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/html')] # HTTP Headers
start_response(status, headers)
return page.getvalue()
Este é um primeiro passo para reescrever o aplicativo CGI em uma estrutura adequada. Isso requer muito pouco trabalho, e fará o seu CGI é muito mais escalável, desde que você não estará começando um processo CGI fresco para cada solicitação.
O segundo passo é criar um servidor mod_wsgi
que o Apache usa em vez de todos os scripts CGI. Esta obrigação servidor (1) analisar o URL, (2) chamar várias funções como o exemplo my_cgi
função. Cada função execfile
o script CGI idade sem bifurcação um novo processo.
werkzeug para bibliotecas votos.
Se seus scripts CGI aplicativos têm alguma estrutura (funções, classes, etc.), você provavelmente pode importar os e fazer algo muito, muito mais esperto do que o anterior. A melhor maneira é isso.
wsgi.py
from my_cgi import this_func, that_func
def my_cgi( environ, start_response ):
result= this_func( some_args )
page_text= that_func( result, some_other_args )
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/html')] # HTTP Headers
start_response(status, headers)
return page_text
Isto requer mais trabalho porque você tem que entender o aplicativo de legado. No entanto, isso tem duas vantagens.
-
Isso faz do seu CGI mais escalável porque você não está começando um processo de fresco para cada solicitação.
-
Ele permite que você repensar a sua aplicação, possivelmente mudá-la para um quadro adequado. Uma vez feito isso, não é muito difícil de dar o próximo passo e ir para TurboGears ou Pilões ou web.py para um quadro muito simples.
Outras dicas
Use FastCGI . Se eu entendi FastCGI corretamente, você pode fazer o que quiser escrevendo um programa Python muito simples que fica entre o servidor web e seu código legado.