V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
SystemLight
V2EX  ›  Python

wsgi 有什么作用?

  •  
  •   SystemLight ·
    SystemLight · 2020-11-10 19:14:18 +08:00 · 2776 次点击
    这是一个创建于 1234 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    14 条回复    2020-11-11 20:50:54 +08:00
    gstqc
        1
    gstqc  
       2020-11-10 19:19:49 +08:00 via Android
    多进程,多服务,运维方便
    GodFastion
        2
    GodFastion  
       2020-11-10 19:22:47 +08:00 via Android
    稳定性要比自带的好得多,自带的只适合开发时使用
    rebeccaMyKid
        3
    rebeccaMyKid  
       2020-11-10 19:40:59 +08:00   ❤️ 2
    以前思考过这个问题。我把以前看过的内容找给你。

    我理解的是:
    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
        4
    johnsona  
       2020-11-10 20:15:43 +08:00   ❤️ 2
    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
        5
    ManjusakaL  
       2020-11-10 20:17:11 +08:00
    因为自带的不具备生产可用性。。。。
    ManjusakaL
        6
    ManjusakaL  
       2020-11-10 20:18:50 +08:00
    BTW WSGI 只是一个标准而已

    其实现有很多种,生产常用的 uWSGI,Gunicron,Web Framework 自带的 如 Flask 的 Werkzurg,Python 官方库内置的 wsgiref 等
    volvo007
        7
    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
        8
    westoy  
       2020-11-10 20:25:17 +08:00
    对接各种上游协议的中间标准
    zjsxwc
        9
    zjsxwc  
       2020-11-10 20:51:34 +08:00 via Android
    wsgi 服务器是 厕所
    python 业务脚本是 马桶

    反正都是用来拉屎的
    a719114136
        10
    a719114136  
       2020-11-11 10:16:08 +08:00
    最大的好处就是各种框架不需要关心 http 相关的东西,不需要自己写监听 http 服务的逻辑,只需要设计好框架自身的东西就行。
    julyclyde
        11
    julyclyde  
       2020-11-11 11:37:00 +08:00
    WSGI 是分离了服务器(通信、进程线程管理)和应用程序的接口
    框架是抽象了 WSGI 传来的信息,包装成常见 Web 概念的软件
    abersheeran
        12
    abersheeran  
       2020-11-11 15:43:48 +08:00
    WSGI/ASGI 都是为了让你可以不用直接面对 HTTP 这个看起来简单,实现起来很复杂的协议的。
    UN2758
        13
    UN2758  
       2020-11-11 18:29:04 +08:00
    @johnsona #4 感谢大佬,想问一下 java 的 servlet 和 springboot 之间的关系就类似 fastcgi 和 flask?servlet 也是对 wsgi 的一种实现吗?
    johnsona
        14
    johnsona  
       2020-11-11 20:50:54 +08:00   ❤️ 1
    @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 是约定大于配置,都把服务器包括进去了好像
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5391 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 06:56 · PVG 14:56 · LAX 23:56 · JFK 02:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.