Python CGI 性能

2 投票
2 回答
3749 浏览
提问于 2025-04-15 12:21

我有一个老旧的Python应用程序,是用CGI写的。到现在为止,这个程序运行得还不错,但不久之后,使用这个程序的用户数量会大幅增加。

我在StackOverflow上看到有人说:“CGI适合流量少的网站,但对于其他情况,它的性能会有一些问题。”我知道如果一开始选择其他方式会更好,但现在CGI就是这样了。

有没有人能给我一些建议,告诉我怎么在不重写所有代码的情况下,让CGI的性能保持良好?

2 个回答

3

使用 FastCGI。如果我理解得没错,FastCGI 让你可以通过写一个非常简单的 Python 程序,把它放在网页服务器和你旧的代码之间,这样就能实现你想要的功能。

6

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

这需要更多的工作,因为你需要理解旧的应用程序。不过,这样做有两个好处。

  1. 它让你的CGI更具扩展性,因为你不需要为每个请求都启动一个新的进程。

  2. 它让你重新思考你的应用程序,可能会将其改成一个合适的框架。一旦你完成了这一步,接下来的步骤就不难了,可以很容易地转向TurboGearsPylonsweb.py等简单框架。

撰写回答