Python cgi 性能

标签 python performance cgi

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

有人能告诉我如何保持 CGI 的性能,而不必重写所有代码吗?

最佳答案

CGI 无法扩展,因为每个请求都会派生一个全新的服务器进程。这是很多开销。 mod_wsgi 通过 fork 一个进程并将请求交给那个正在运行的进程来避免开销。

让我们假设应用程序是最糟糕的一种 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 并不难。或 Pylonsweb.py一个非常简单的框架。

关于Python cgi 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1017087/

相关文章:

javascript - 智能手机作为服务器

python - python 中的科学记数法

python - Unicode 该死的 : detwingle crashes on a website

python - 存在哪些模板系统适合编写服务创建配方

python - 使用 cgitb 获取 HTML 正文

python - python cgi 和 python django 之间的单点登录

java - 只有一个部署在 Tomcat 中运行缓慢,另一个运行正常/快速

performance - 奇怪的 get 优化行为

scala - 获取两个列表的元素总和的最快方法

javascript - 获取模板复选框名称