启动web应用程序 - PHP, Ruby, Python, Node.js

4 投票
1 回答
1190 浏览
提问于 2025-04-18 12:35

假设1:当通过apache或nginx运行PHP时,每次接收到请求,都会重新加载所有的包含文件。也就是说,没有共享内存,每次请求时“世界都会被重建”。

假设2:Node.js应用在服务器启动时就已经加载好了。“世界只创建一次”。

那么,Python和Ruby的应用加载方式是跟PHP一样,还是跟Node.js一样呢?

如果可以的话,希望能得到一些关于术语的指导:这基本上是关于多线程还是并发支持的问题吗?

1 个回答

2

这完全取决于应用程序的运行方式。

大多数用Python写的网页应用程序都是作为服务器运行的,它们接收请求,而不是像“死”脚本那样在请求时被调用。“在请求到达之前,世界就已经创建好了”。

注意,我没有说“只运行一次”,就像你说的那样。

我这样说是因为有不同的方式来提供Python网页应用。

大多数Python(网页)应用都是'WSGI'应用。WSGI是一种规范,基本上要求应用程序(或框架)有一个单一的入口函数:

def app(environment, start_response):

这里的environment包含了请求的地址、cookies、请求类型、查询参数等等。start_response是一个回调函数,app函数需要用响应的HTTP代码和头信息来调用它。

    start_response('200 OK', [('Content-type', 'text/html')])

例如,一旦调用了这个函数,函数要么需要return响应的主体返回给客户端,要么以生成器的方式yield返回(适用于超大文件)。

所有这些通常由一个WSGI框架处理,它透明地完成这些工作,并提供一个更容易编写的接口来编写你的应用逻辑。

在PHP中,所有的路由和路由处理通常由apache(或nginx/php-fpm)来运行单独的脚本文件。正如你所说的,这需要每次都重新创建整个世界。使用WSGI时,世界已经创建好了,WSGI只需在每次新请求到来时调用应用函数。大多数基于Python的网页框架都有某种路由器,可能是flask风格:

@app.route('/elephants')
def elephants_view():
    return 'view the elephants!'

或者Django风格的路由表:

urls = [
    (r'^/kangaroos$', 'views.kangaroos'),
    ]

# in views.py:
def kangaroos():
    return 'kangaroos, baby!'

或者其他方式。有很多不同的WSGI框架,各有优缺点。一些流行的基于WSGI的框架包括FlaskDjangoFalcon

提供WSGI应用的方式有很多。Flask和Django自带基本的开发服务器,这些服务器是单线程的,适合开发,但不适合生产环境。

因为它们是单线程的,“世界只创建一次”。所以全局变量在请求之间是持久的等等。

还有很多其他的WSGI服务器,可以为任何基于WSGI的框架提供服务。Waitress是一个很棒的纯Python服务器。uWSGI是另一个适合生产环境的服务器,还有gUnicorn,以及其他很多。

这些服务器保证全局状态在请求之间共享,并且会以未指定(可配置)的次数“创建世界”。其中一些使用固定数量的工作进程,主接收器会将请求分配给它们,其他的可能会根据需要启动新的工作线程或进程。

Flask和大多数其他Python WSGI框架都有'应用全局变量'的概念,这样你就可以存储在整个服务器生命周期内必须存在的数据。这些特殊值在“世界”之间是共享的。(通过在森林中使用魔法环和池子)。

(顺便提一下:为了好玩,我开始写一个WSGI服务器,使用非常酷的gevent异步库,它的工作方式与Node.js类似,都是单进程,尽可能地异步处理(虽然没有Node.js的回调风格...)在一个线程中。它非常简短,只有一个文件,所以很容易看出它是如何工作的。)

Ruby在这方面与Python非常相似,只是协议叫做'Rack',而常见的服务器有'Puma'、'Unicorn'和'Rainbows!'。常见的基于Ruby Rack的框架有'Ruby on Rails'、'Sinatra'和'Merb'。

这种模型的一个优点是你可以创建“中间件”,它位于应用响应者和WSGI(或Rack)服务器之间,可以在请求的过程中“做一些事情”(例如压缩JavaScript、缓存、记录日志、身份验证等)。

另一个很好的WSGI介绍及其工作原理的资料可以在'Full stack Python'找到。

除了使用WSGI(或Rack)之外,还有其他方式编写网页服务器。例如,Python中的TornadoTwisted框架允许编写完全不同的异步风格的(网页)应用。它们也使用“在请求到来之前创建世界”的服务器风格。

撰写回答