在mod_python上部署WSGI应用程序

5 投票
4 回答
1173 浏览
提问于 2025-04-17 04:55

我写了一个WSGI应用程序,现在需要把它部署到服务器上。不过,我得到的服务器上已经安装了mod_python。

我不能卸载mod_python,因为服务器上已经有一些mod_python的应用在运行。

我考虑过一个选项,就是在mod_python的基础上安装mod_wsgi,但我查了一下资料,发现这样做不好。听说mod_wsgi和mod_python不太兼容。

我还考虑过安装mod_fastcgi,然后用fastcgi来部署。

我很想知道有没有人有更好的主意,能在不影响当前mod_python应用的情况下进行部署。

4 个回答

1

最好的解决办法可能是使用mod_proxy,并在另一个网络服务器上运行Python网络应用。

2

这里有个想法(需要进一步完善,可能也不一定可行):

  • 它使用了 wsgiref.handlers.BaseHandler
  • wsgiref 是 Python 标准库的一部分
  • 根据 wsgiref 的文档:“在尝试创建自定义的 BaseHandler 子类之前,您应该查看文档字符串和源代码以获取更多信息。”
  • (下面的代码是 mod_python 处理模块,顺便提一下)

我会从这里开始:

from mod_python import apache
from wsgiref.handlers import BaseHandler

class MyWSGIHandler(BaseHandler):
    def __init__(self, apachereq):
        BaseHandler.__init__(self)
        self.apachereq = apachereq

    def _write(self, data):
        self.apachereq.write(data)

    # override the other required methods of BaseHandler, see
    # http://docs.python.org/library/wsgiref.html#wsgiref.handlers.BaseHandler

wsgi_app = create_your_wsgi_app()

def handler(req):
    wsgi_handler = MyWSGIHandler(req)
    wsgi_handler.run(wsgi_app)
    return apache.OK

想法 2(有点黑科技):

你可以在你的处理代码中使用 werkzeug wsgi 测试模块 来将请求传递给 WSGI 应用,获取一个 werkzeug 的响应,然后将这个响应写入到 Apache。

大概是这样的:

from mod_python import apache
from werkzeug.test import Client
from werkzeug.wrappers import BaseResponse

wsgi_app = create_your_wsgi_app()

def handler(req):
    c = Client(wsgi_app, BaseResponse)
    resp = c.get(somehow_get_the_url_from(req)) # or c.post if it's a POST request
    req.write(resp.data) # ... and find a way to write the headers as well
    return apache.OK
3

你可以同时使用mod_python和mod_wsgi,只要它们使用的是相同的Python版本,并且mod_python没有链接到一个静态的Python库。

你可以在mod_python.so文件上运行'ldd'命令:

ldd mod_python.so

这样可以检查它是否链接到libpythonX.Y.so。然后,构建mod_wsgi时也要使用相同的Python版本,并确保它同样链接到libpythonX.Y.so。


更新

mod_wsgi的4.X版本现在明确表示,如果同时加载mod_python,它将拒绝启动。为了让mod_python和mod_wsgi一起使用,mod_wsgi的一些功能不得不被削弱。由于mod_python现在非常老旧,几乎没有更新,存在各种问题,不应该再用于新的项目,因此不再尝试支持它们一起使用。

撰写回答