wsgi 有什么作用?

2020-11-10 19:14:18 +08:00
 SystemLight

python 中的 web 框架可以直接运行 web 程序,浏览器可以直接访问,但是为什一般部署的时候还需要 nginx+wsgi 这种模式去部署呢,如 flask,Django,tornado,为什么不是直接把程序放到服务器上并运行呢。

2804 次点击
所在节点    Python
14 条回复
gstqc
2020-11-10 19:19:49 +08:00
多进程,多服务,运维方便
GodFastion
2020-11-10 19:22:47 +08:00
稳定性要比自带的好得多,自带的只适合开发时使用
rebeccaMyKid
2020-11-10 19:40:59 +08:00
以前思考过这个问题。我把以前看过的内容找给你。

我理解的是:
1. flash 是个 webframework,是个框架,不是 http 服务器或者 wsgi 服务器. 另外两个不知道,估计也是一样的。
2. 框架只是把服务器接收到的东西给你模块化处理了。你写个 CGI 就知道有多麻烦了。

我没记错的话,好像多是 Nginx + Gunicorn + flask 的模式,Gunicorn 是 flask 的容器,是一个 server 。看这个问题 https://stackoverflow.com/questions/20766684/what-benefit-is-added-by-using-gunicorn-nginx-flask?noredirect=1&lq=1

然后为什么还要在 Gunicorn 这个 server 外面还加一个 Nginx,看这个 https://serverfault.com/questions/220046/why-is-setting-nginx-as-a-reverse-proxy-a-good-idea 。我看过不是很懂。

WSGI 是一种协议,比如,我没记错的话,nginx 和 Gunicorn 之间可以用 WSGI 协议通信,Gunicorn 好像同时支持 HTTP 协议和 WSGI 协议。

然后你说的“为什么不直接把程序放到服务器上运行呢”? 看这个 https://docs.python.org/3.4/howto/webservers.html?highlight=cgi,这里讲了 cgi, mod_python,再到 fast_cgi,再到 wsgi 的演变。具体理由我忘了。

要明白这些,我估计你还得了解一下 web 服务器是怎么调用”框架“的。我大概有个印象,但不是特别清楚。比如你可以了解一下 apache 是怎么调用 mod_python 的,mod_python 我记得是 apache 自己的一个模块,而 fast_cgi,wsgi 这种都是另外会起一个进程,进程间通信。

我感觉要搞明白得花 1~2 周?你得自己写写 CGI 什么的。另外你可以看看 flask 文档的几种部署方式,对你理解这个应该也有帮助。(最后一个链接的内容比较重要)
johnsona
2020-11-10 20:15:43 +08:00
1.你要区分 http 服务器和应用框架。http 服务器是接收 http 请求,然后调用你写的框架逻辑(比如 flask ),处理请求,返回结果。http 服务器和应用框架之间交互的协议就叫 wsgi,协议具体来说就是 http 服务器把请求和回调函数给应用框架,应用框架处理完请求之后,执行 http 服务器给的回调函数,把结果给到 http 服务器,http 服务器返回结果给前端。
2.flask django 都自带了 http 服务器在里面,但是不够好,不够稳定,并发不够高等等
所以一般用 uwsgi 或者 gunicorn 这种 http 服务器替代
3.nginx 可用可不用,一般来说 nginx 是作为 uwsgi 或者 gunicorn 这种 http 服务器的反向代理,就是说 nginx 把请求拿到了,给到 gunicorn,gunicorn 调用 flask 代码执行逻辑。nginx,uwsig,gunicorn 。他们都是 http 服务器,或者有时候又叫 gunicorn 这种叫应用服务器。为什么要用?因为 nginx 能处理很高的并发,而且 nginx 在加载静态资源比如 html,css,js 时候非常快,当然加载静态资源就不叫反向代理了,就是去打开 html 这些文件返回给客户端而已
ManjusakaL
2020-11-10 20:17:11 +08:00
因为自带的不具备生产可用性。。。。
ManjusakaL
2020-11-10 20:18:50 +08:00
BTW WSGI 只是一个标准而已

其实现有很多种,生产常用的 uWSGI,Gunicron,Web Framework 自带的 如 Flask 的 Werkzurg,Python 官方库内置的 wsgiref 等
volvo007
2020-11-10 20:22:36 +08:00
这个问题我也想过很久,一开始也是糊涂

flask 自带一个 wsgi 框架,这个测试框架决定了用户可以通过 flask run 跑一个 server 让其他人访问
但是这个框架的性能很差,撑不住很多用户访问

所以可以用其他 wsgi 协议的 wsgi 框架(我没记错的话,wsgi 既可以指一种通信协议,又可以指基于这种协议的一种组件类型)
用了这些框架之后,来自 http/https 的请求,会通过这种协议和 server 通信,比如返回 server 上的某个 url 下的特定页面等

至于 nginx,主要是为了提高承载量,基于 C 的。另一方面,它的反向代理可以让你在部署网站的时候,不用写 www.abc.com:5555 这种带端口的东西,可以让 nginx 反向代理:我发现来自 80 和 8080 端口的,请求 www.abc.com/index 的,我就指向后台服务本身的端口比如 5555,以实现端口隐藏
westoy
2020-11-10 20:25:17 +08:00
对接各种上游协议的中间标准
zjsxwc
2020-11-10 20:51:34 +08:00
wsgi 服务器是 厕所
python 业务脚本是 马桶

反正都是用来拉屎的
a719114136
2020-11-11 10:16:08 +08:00
最大的好处就是各种框架不需要关心 http 相关的东西,不需要自己写监听 http 服务的逻辑,只需要设计好框架自身的东西就行。
julyclyde
2020-11-11 11:37:00 +08:00
WSGI 是分离了服务器(通信、进程线程管理)和应用程序的接口
框架是抽象了 WSGI 传来的信息,包装成常见 Web 概念的软件
abersheeran
2020-11-11 15:43:48 +08:00
WSGI/ASGI 都是为了让你可以不用直接面对 HTTP 这个看起来简单,实现起来很复杂的协议的。
UN2758
2020-11-11 18:29:04 +08:00
@johnsona #4 感谢大佬,想问一下 java 的 servlet 和 springboot 之间的关系就类似 fastcgi 和 flask?servlet 也是对 wsgi 的一种实现吗?
johnsona
2020-11-11 20:50:54 +08:00
@UN2758 wsgi 是 http server 和 python web 框架之间交互的协议。全称是 Python Web Server Gateway Interface,就是 python 网关协议,所以和 servlet 不一样。而 wsgi server 就是符合 wsgi 协议的 http 服务器,python web 框架就是 flask 这些。
具体点,你可以把 wsgi server 理解成一个程序,里面就开了一个 socket 在 while 循环接受请求,然后把 http 请求报文直接给 python web 框架,web 框架根据 http 的请求的 url,做不同处理,这叫路由, 处理完了,我再把结果变成 http resposne 给 http 服务器,让他给客户端,怎么给,就是回调函数。

```python
def app(environ, start_response):
data = b"Hello, World!\n"
start_response("200 OK", [
("Content-Type", "text/plain"),
("Content-Length", str(len(data)))
])
return iter([data])
```
感觉自己也更清楚了呢
至于 servlet 和 sprintboot,不是很清楚,应该差不多,springboot 是约定大于配置,都把服务器包括进去了好像

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/723702

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX