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
revotu
V2EX  ›  Python

django 作为 web 服务器为什么线上部署的时候要用到 uwsgi 和 nginx 啊

  •  
  •   revotu · 2017-07-16 22:40:29 +08:00 · 11337 次点击
    这是一个创建于 2475 天前的主题,其中的信息可能已经有所发展或是发生改变。
    部署 django 的线上环境时,通常要搭配 nginx 和 uwsgi,但是实在不懂,他们之间的明确关系,到底都是必须的么,为什么本地环境就一个 django 就可以了,怎么到了线上,还需要 nginx 和 uwsgi,不理解
    14 条回复    2017-07-21 23:21:48 +08:00
    ywgx
        1
    ywgx  
       2017-07-16 23:12:34 +08:00   ❤️ 2
    一个成熟的站点提供服务,需要 Web 服务器 [静态数据] 和 App 服务器[动态数据]

    Web 服务器目前属 Nginx 最强大,请求代理过来后,把数据返回给请求客户端,但是目前的互联网发展时代,都是包含动态数据处理的,这样一般 Nginx 不处理业务逻辑,就外包给后端的 App 服务器,这里就是你的 django 服务器

    当然目前有些全功能的 Web 服务器开发模式已经出现,比如 OpenResty , 可以预见,未来有更多的业务逻辑前置在 Web 服务器内部实现
    troywinter
        2
    troywinter  
       2017-07-16 23:31:33 +08:00
    建议你去了解一下 wsgi 和 gUnicorn,uWsgi 这些应用服务器的作用。
    ipwx
        3
    ipwx  
       2017-07-16 23:35:30 +08:00   ❤️ 1
    因为标准 Python 只能是是单线程,无法并发,而 uwsgi / gunicorn 通过多进程池达成了更暴力的并发。

    至于 nginx,你静态文件都走 Python 程序,不是浪费机器性能嘛?
    alexapollo
        4
    alexapollo  
       2017-07-16 23:42:14 +08:00
    其实楼主问题对开源社区挺关键的
    sylecn
        5
    sylecn  
       2017-07-17 00:37:27 +08:00 via Android   ❤️ 1
    生产环境怎么部署 Django 是性能和安全方面的需求决定的。

    Django 的内置 server 性能有多差,你用 ab 之类的工具压测一下就知道了。

    在需要性能的场合,通常单单 nginx 和 uwsgi 也是不够的。nginx 主要优化的是连接数和静态文件。uwsgi 主要优化的是 wsgi 服务。这些都只是手段。其它手段包括,优化数据库,增加缓存,加入负载均衡器,引入异步 IO 框架,计算密集型模块用 C 重写等。

    安全性方面,也会有很多考虑,这里不展开。
    ryd994
        6
    ryd994  
       2017-07-17 09:15:36 +08:00   ❤️ 2
    因为 Django 根本不是 http 服务器,而是 web 框架,本就是要搭配 uwsgi 和 /或 nginx 用的
    只不过开发组体谅用户,自带一个简易的调试用服务器,那是不能用于生产的

    @ipwx gunicorn 的 gevent 模式也挺强大的,虽然比不上 Nginx,未必比不过 Apache
    kios
        7
    kios  
       2017-07-17 11:30:32 +08:00
    同样 以前也有这样的疑惑。感谢分享
    zhengxiaowai
        8
    zhengxiaowai  
       2017-07-17 13:30:00 +08:00   ❤️ 2
    首先你要明确几个概念及其作用(注意大小写的区别):

    - WSGI
    - uWSGI
    - uwsgi
    - Nginx

    WSGI 是一种协议,不是任何包不是任何服务器,就和 TCP 协议一样。它定义了 Web 服务器和 Web 应用程序之前如何通信的规范。

    至于为什么和 Python 扯在一起?因为这个协议是由 Python 在 2003 年提出的。(参考:PEP-333 和 PEP-3333 )

    > WSGI is the Web Server Gateway Interface. It is a specification that describes how a web server communicates with web applications, and how web applications can be chained together to process one request.

    uWSGI 是一个全功能的 HTTP 服务器,他要做的就是把 HTTP 协议转化成语言支持的网络协议。比如把 HTTP 协议转化成 WSGI 协议,让 Python 可以直接使用。

    > The uWSGI project aims at developing a full stack for building hosting services.
    >
    > Application servers (for various programming languages and protocols), proxies, process managers and monitors are all implemented using a common api and a common configuration style.

    uwsgi 是一种 uWSGI 的内部协议,使用二进制方式和其他应用程序进行通信。

    > The uwsgi (lowercase!) protocol is the native protocol used by the uWSGI server.
    >
    > It is a binary protocol that can carry any type of data. The first 4 bytes of a uwsgi packet describe the type of the data contained by the packet.

    Nginx 是一个 Web 服务器其中的 HTTP 服务器功能和 uWSGI 功能很类似,但是 Nginx 还可以用作更多用途,比如最常用的反向代理功能。

    所以用一张图来描述一下这个过程:

    ![]( https://cdn.hexiangyu.me/images/WSGI%20%E7%A8%8B%E5%BA%8F%E9%83%A8%E7%BD%B2%E6%A0%88.png)

    **接下是为什么不能用 Django 的 Web 服务器直接部署**

    Django 是一个 Web 框架,框架的作用在于处理 request 和 reponse,其他的不是框架所关心的内容。所以怎么部署 Django 不是 Django 所需要关心的。

    Django 所提供的是一个开发服务器,这个开发服务器,没有经过安全测试,而且使用的是 Python 自带的 simple HTTPServer 创建的,在安全性和效率上都是不行的。

    > DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through security audits or performance tests.

    在 Django 源码中可以很清楚的看出来,runserver 起来的 HTTPServer 就是 Python 自带的 simple_server。

    > 以下是最新版本 Django 有关 runserver command 的代码节选

    - [django.core.management.commands.runserver.Command:run]( https://github.com/django/django/blob/master/django/core/management/commands/runserver.py#L100-L107)
    - [django.core.management.commands.runserver.Command:inner_run]( https://github.com/django/django/blob/master/django/core/management/commands/runserver.py#L141-L142)

    其中 inner_run 函数中的 run 方法和 run 方法中 server_cls 参数分别取自 [django.core.servers.basehttp:run]( https://github.com/django/django/blob/master/django/core/servers/basehttp.py#L164-L180) 和 [django.core.servers.basehttp:WSGIServer]( https://github.com/django/django/blob/master/django/core/servers/basehttp.py#L57-L73)

    而 WSGIServer 又的父类就是 wsgiref.simple_server。既然是 simple 了很多东西都是不太可以的。

    **既然 uWSGI 可以完成 Nginx 功能,那为什么又要用 Nginx**

    因为 Nginx 牛逼啊,能直接在 Ninx 层面就完成很多事情,比如静态文件、反向代理、转发等需求。

    ## 参考

    - [WSGI 官方文档]( https://wsgi.readthedocs.io/en/latest/index.html)
    - [uWSGI 官方文档]( http://uwsgi-docs.readthedocs.io/en/latest/index.html)
    - [Django django-admin runserver]( https://docs.djangoproject.com/en/1.11/ref/django-admin/#runserver)
    zhengxiaowai
        9
    zhengxiaowai  
       2017-07-17 13:31:11 +08:00
    话说回复不支持 markdown 啊?
    revotu
        10
    revotu  
    OP
       2017-07-17 14:18:22 +08:00
    @zhengxiaowai 多谢讲解的这么细致及相关资源链接,我这种小白学到了不少。话说回复确实不支持 markdown,我之前也好奇为啥回复不支持 markdown 啊
    sangmong
        11
    sangmong  
       2017-07-17 22:14:49 +08:00
    学习一下嘿嘿
    yylucifer
        12
    yylucifer  
       2017-07-18 11:12:25 +08:00
    @troywinter 确定不是 web 服务器?[/坏笑]
    mlyy
        13
    mlyy  
       2017-07-20 00:41:48 +08:00
    搭车求问。那形如 aiohttp 或者 sanic 这种本身就是基于异步 IO 框架的 web 框架还需要这样部署吗?@zhengxiaowai
    zhengxiaowai
        14
    zhengxiaowai  
       2017-07-21 23:21:48 +08:00   ❤️ 1
    @mlyy uwsgi 是同步的,异步的可以选择 gunicorn gevent 部署
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1107 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:38 · PVG 06:38 · LAX 15:38 · JFK 18:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.