Python网页托管:为什么需要重启服务器?
我们现在在服务器上运行一个小型的共享主机服务,支持几百个小型的PHP网站。我们也想提供Python的支持,但根据我们初步的研究,似乎每次修改源代码后都需要重启服务器。
这真的是这样吗?如果是的话,那我们就没办法提供Python的主机支持了。让客户上传文件很简单,但我们不能让他们去重启(共享)服务器进程啊!
PHP很简单——你只需要上传一个新版本的文件,新的版本就会被运行。
我对Python语言和社区非常尊重,所以很难相信更新网站代码真的需要这么复杂的过程。请告诉我我错了!:-)
3 个回答
这真的是这样吗?
这要看情况。代码重新加载的方式很大程度上取决于你使用的服务器。大多数服务器都有某种方法可以自动重新加载 WSGI 脚本,但并没有统一的标准;实际上,WSGI 应用程序对象是如何与网络服务器连接的,在不同的托管环境中差别很大。(你几乎可以写一个单独的脚本文件,作为 CGI、mod_wsgi、passenger 和 ISAPI_WSGI 的连接工具,但这并不是一件简单的事。)
不过,Python 在模块重新加载方面确实遇到了一些困难。这对 WSGI 应用程序来说是个问题,因为任何复杂的网页应用都会把功能封装到模块和包中,而不是简单的独立脚本。重新加载模块其实挺麻烦的,因为如果你一个个地 reload()
它们,可能会出现指向旧版本的错误引用。理想的做法是,当任何文件更新时,重新加载整个 Python 解释器,但实际上似乎一些 C 扩展不太喜欢这样,所以通常不会这么做。
有一些解决方法可以一次性重新加载一组模块,这样在更新某个模块时,可以可靠地更新应用程序。我使用了一个部署模块来实现这个功能(我还没来得及发布,但如果你感兴趣可以给你一份),它对我自己的网页应用效果很好。不过,你需要稍微注意一下,确保不会在其他没有重新加载的模块中留下对旧模块对象的引用;如果你在处理很多第三方编写的网站,而这些代码可能有问题,那就不太理想了。
在这种情况下,你可能想考虑使用 daemon 模式运行 mod_wsgi,为每个方创建一个应用组,并进行进程级的重新加载,当你更新任何模块时,触碰一下 WSGI 脚本文件。
你抱怨得对;这个问题(以及许多其他 WSGI 部署问题)确实需要一些标准化的帮助。
这要看你是怎么部署你的Python应用的。如果你是用纯Python的CGI脚本,那就不需要重启(不过这样做不太好,因为会非常慢)。如果你是在Apache上使用mod_wsgi,有一些有效的方法可以重新加载源代码。而mod_python似乎对模块重载有一些支持和相关问题。
除了Apache,还有其他方法可以托管Python应用,比如CherryPy服务器、Paste服务器、Zope、Twisted和Tornado。
不过,除非你有特别的理由不使用它(而且你可能是从Apache/PHP环境过来的),我强烈推荐在Apache上使用mod_wsgi。我知道Django推荐在Apache上使用mod_wsgi,而且大多数其他主要的Python框架也能在mod_wsgi上运行。
Python是一种编译语言;它会把编译后的字节码缓存起来,以便后续使用,这样可以提高运行速度。而PHP默认是解释型语言。这两者之间是可用性和速度的权衡。
如果你使用的是标准的WSGI模块,比如Apache的mod_wsgi
,那么你不需要重启服务器,只需修改一下.wsgi
文件,代码就会自动重新加载。如果你用的是一些不支持WSGI的奇怪服务器,那就得自己想办法了,使用起来可能会比较麻烦。