我拥有一个以CGI编写的遗留python应用程序。到目前为止,这可以正常工作,但并发用户的数量将在不久的将来大幅增加。 在这里,我读到:“CGI非常适合低流量网站,但它有其他任何性能问题”。我知道以另一种方式开始会更好,但CGI就是现在的样子。

有人可以指点我如何保持CGI的表现,而不必重写所有代码?

有帮助吗?

解决方案

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流程。

第二步是创建Apache使用的 mod_wsgi 服务器,而不是所有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. 它允许您重新考虑您的应用程序,可能将其更改为适当的框架。完成此操作后,下一步并转到 TurboGears Pylons web.py 对于一个非常简单的框架。

其他提示

使用 FastCGI 。如果我正确理解FastCGI,你可以通过编写一个位于Web服务器和遗留代码之间的非常简单的Python程序来做你想做的事。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top