我拥有一个写成CGI的遗留Python应用程序。到目前为止,这工作正常,但并发用户的数量将在不久的将来大幅增加。 在这里我读到:“CGI适合低流量的网站,但它对于其他任何东西都有一些性能问题。我知道以另一种方式开始会更好,但CGI是现在的情况。Python cgi性能
有人可以指点我如何保持CGI的表现,而不必重写所有的代码?
我拥有一个写成CGI的遗留Python应用程序。到目前为止,这工作正常,但并发用户的数量将在不久的将来大幅增加。 在这里我读到:“CGI适合低流量的网站,但它对于其他任何东西都有一些性能问题。我知道以另一种方式开始会更好,但CGI是现在的情况。Python 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
这需要更多的工作,因为你必须要了解的遗留应用程序。但是,这有两个好处。
它使您的CGI具有更高的可扩展性,因为您没有为每个请求启动新的过程。
它允许您重新考虑您的应用程序,可能会将其更改为适当的框架。一旦你完成了这个任务,就不难做出下一个步骤,并且转向TurboGears或Pylons或web.py来构建一个非常简单的框架。
使用FastCGI。如果我正确理解FastCGI,那么可以通过编写一个位于Web服务器和旧代码之间的非常简单的Python程序来执行您想要的操作。
感谢您的详细回复。我的应用程序是最糟糕的一种。 不得不改变调用gi.FieldStorage(),MySQLdb和使用os模块的事情吗? – user37986 2009-06-19 12:27:35