2009-06-19 6 views
2

Je possède une ancienne application python écrite en CGI. Jusqu'à présent, cela fonctionne bien, mais le nombre d'utilisateurs simultanés augmentera considérablement dans un très proche avenir. Ici, sur SO, je lis: "CGI est idéal pour les sites à faible trafic, mais il a des problèmes de performances pour tout le reste". Je sais qu'il aurait été préférable de commencer autrement, mais CGI est ce qu'elle est maintenant.Python cgi performance

Est-ce que quelqu'un pourrait m'indiquer comment garder le CGI sans avoir à réécrire tout le code?

Répondre

6

Le CGI n'est pas mis à l'échelle, car chaque requête crée un tout nouveau processus serveur. C'est beaucoup de frais généraux. mod_wsgi évite le surcoût en forçant un processus et en transmettant des requêtes à ce processus en cours.

Supposons que l'application est la pire sorte de CGI.

Le pire des cas est qu'il a des fichiers comme celui-ci.

my_cgi.py

import cgi 
print "status: 200 OK" 
print "content-type: text/html" 
print 
print "<!doctype...>" 
print "<html>" 
etc. 

Vous pouvez essayer de "envelopper" les fichiers CGI originaux pour le rendre 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() 

Cette première étape de réécriture de votre application CGI dans un cadre approprié. Cela nécessite très peu de travail et rendra vos CGI beaucoup plus évolutifs, puisque vous ne lancerez pas un nouveau processus CGI pour chaque requête.

La deuxième étape consiste à créer un serveur mod_wsgi utilisé par Apache au lieu de tous les scripts CGI. Ce serveur doit (1) analyser les URL, (2) appeler différentes fonctions comme la fonction exemple my_cgi. Chaque fonction execfile l'ancien script CGI sans forcer un nouveau processus. Voir werkzeug pour les bibliothèques utiles. Si les scripts CGI de votre application ont une structure (fonctions, classes, etc.), vous pouvez probablement les importer et faire quelque chose de beaucoup plus intelligent que ce qui est indiqué ci-dessus. Une meilleure façon est-ce.

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 

Cela nécessite plus de travail parce que vous devez comprendre l'application héritée. Cependant, cela a deux avantages.

  1. Cela rend vos CGI plus évolutifs car vous ne démarrez pas un nouveau processus pour chaque requête.

  2. Il vous permet de repenser votre application, en la modifiant éventuellement dans un cadre approprié. Une fois que vous avez fait cela, il n'est pas très difficile de passer à l'étape suivante et passer à TurboGears ou Pylons ou web.py pour un cadre très simple.

+0

Merci pour la réponse élaborée. Mon application est de la pire sorte. Y aura-t-il des problèmes à devoir changer les appels à gi.FieldStorage(), MySQLdb et des choses comme l'utilisation du module os? – user37986

+1

Jamais. La seule chose qui va casser quand vous passez de mauvais cgi à fastcgi ou mod_wsgi est l'instruction 'print'. La sortie de l'instruction 'print' fonctionne pour cgi, mais ne fonctionne pas ailleurs. –

3

Utilisez FastCGI. Si je comprends bien FastCGI, vous pouvez faire ce que vous voulez en écrivant un programme Python très simple qui se trouve entre le serveur Web et votre code existant.