Python CGI 性能
我有一个老旧的Python应用程序,是用CGI写的。到现在为止,这个程序运行得还不错,但不久之后,使用这个程序的用户数量会大幅增加。
我在StackOverflow上看到有人说:“CGI适合流量少的网站,但对于其他情况,它的性能会有一些问题。”我知道如果一开始选择其他方式会更好,但现在CGI就是这样了。
有没有人能给我一些建议,告诉我怎么在不重写所有代码的情况下,让CGI的性能保持良好?
2 个回答
使用 FastCGI。如果我理解得没错,FastCGI 让你可以通过写一个非常简单的 Python 程序,把它放在网页服务器和你旧的代码之间,这样就能实现你想要的功能。
CGI(通用网关接口)不太适合大规模使用,因为每次请求都会启动一个全新的服务器进程。这会消耗很多资源。mod_wsgi通过只启动一个进程来处理请求,避免了这种资源浪费。
假设这个应用程序是最糟糕的CGI类型。
最糟糕的情况是它有这样的文件。
my_cgi.py
import cgi
print "status: 200 OK"
print "content-type: text/html"
print
print "<!doctype...>"
print "<html>"
etc.
你可以尝试把原来的CGI文件“包装”成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()
这是将你的CGI应用程序改写成一个合适框架的第一步。这需要的工作很少,而且会让你的CGI变得更具扩展性,因为你不会为每个请求都启动一个新的CGI进程。
第二步是创建一个mod_wsgi
服务器,让Apache使用它来代替所有的CGI脚本。这个服务器必须 (1) 解析URL, (2) 调用各种函数,比如my_cgi
示例函数。每个函数会使用execfile
来执行旧的CGI脚本,而不会启动新的进程。
可以查看werkzeug来获取一些有用的库。
如果你的CGI脚本有一些结构(比如函数、类等),你可能可以导入这些内容,做一些比上面更聪明的事情。更好的方法是这样的。
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
这需要更多的工作,因为你需要理解旧的应用程序。不过,这样做有两个好处。
它让你的CGI更具扩展性,因为你不需要为每个请求都启动一个新的进程。
它让你重新思考你的应用程序,可能会将其改成一个合适的框架。一旦你完成了这一步,接下来的步骤就不难了,可以很容易地转向TurboGears、Pylons或web.py等简单框架。