V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
feng32
V2EX  ›  程序员

为什么 flask run 不建议用于生产环境?

  •  
  •   feng32 · 2020-07-21 10:52:23 +08:00 · 5136 次点击
    这是一个创建于 1346 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如果预计的负载小于 1 qps,可以安全地直接使用 flask run 提供服务吗?

    FLASK_APP=admin.py flask run
     * Serving Flask app "admin.py"
     * Environment: production
       WARNING: This is a development server. Do not use it in a production deployment.
       Use a production WSGI server instead.
     * Debug mode: off
     * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
    
    19 条回复    2020-07-23 11:23:14 +08:00
    la2la
        1
    la2la  
       2020-07-21 11:11:25 +08:00
    做个性能测试就体现出来了。
    welkinzh
        2
    welkinzh  
       2020-07-21 11:19:47 +08:00
    你说的这个情况真要用也不是不行,不过裸跑 flask 没有服务挂了自动重启,访问量上来了自动扩容等等功能
    minami
        3
    minami  
       2020-07-21 11:28:20 +08:00
    用 gunicorn 啊,多好用
    hakono
        4
    hakono  
       2020-07-21 11:34:44 +08:00 via Android
    不让用在生产环境是因为这么搞性能很差
    但楼主你这负载小于 1qps 。。。。直接 flask run 没问题
    renmu123
        5
    renmu123  
       2020-07-21 12:40:48 +08:00 via Android
    推荐 gunicorn,很方便,一个命令就可以了,再套层 NGINX
    GrayXu
        6
    GrayXu  
       2020-07-21 15:45:40 +08:00
    加一个中间层其实要做的事情很少,不过负载量小的话当然也无所谓了
    wuwukai007
        7
    wuwukai007  
       2020-07-21 15:46:40 +08:00 via Android
    开发服务器长时间运行有大概率会假死的,
    hunk
        8
    hunk  
       2020-07-21 15:52:36 +08:00
    @renmu123 gunicorn nginx +1
    Hardrain
        9
    Hardrain  
       2020-07-21 16:11:21 +08:00 via Android
    因为 werkzeug 的进程模型没有考虑生产环境需要的性能

    生产环境应该用 gunicorn/uwsgi 这类 wsgi 服务器,或者 mod_wsgi 这种嵌入 Web 服务器的实现
    Firxiao
        10
    Firxiao  
       2020-07-21 17:16:46 +08:00
    太长不看: 编写一个健壮、快速和可伸缩的 HTTP 服务器绝非易事,它需要的不仅仅是“支持多线程多进程”。

    [文档]( https://werkzeug.palletsprojects.com/en/1.0.x/serving/)说的是你不应该在生产中使用开发服务器:

    开发服务器不打算用于生产系统。它是专门为开发目的而设计的,在高负载下性能很差。

    这并不妨碍您在 werkzeug 上构建您的应用程序(希望如此),您只是想使用可用于生产的 HTTP 服务器进行部署。

    至于原因,上面已经清楚地说明了:此开发服务器的设计不是为了在负载下正确执行,而是作为一种实际的开发工具。正确处理负载是一个相当复杂的问题,这就是为什么有专门的 HTTP 服务器,如 nginx, apache 等——它们几乎都是用 C 语言编写的——关注稳定性和性能。因此,如果您试图在生产环境中使用 werkzeug 的开发服务器,那么它将在负载下变得非常慢,以至于您的站点将完全无法使用。您可能还会遇到内存使用问题(这可能会导致您的服务器崩溃)和安全问题——这两个问题对于一个专用的、经过调试和优化的 HTTP 服务器来说是很难正确处理的。

    搬运+有道翻译
    https://stackoverflow.com/questions/50152641/why-cant-use-werkzeug-in-production
    volvo007
        11
    volvo007  
       2020-07-21 17:54:26 +08:00 via iPhone   ❤️ 3
    这是 flask 和 Django 很不一样的地方,我一开始也困惑了很久

    简单说,flask 需要有一个中间件( wsgi )去让 flask 进程挂靠,flask 的 app 才能跑起来

    为了开发方便,flask 自己也实现了一个简单的 wsgi 组件,但这个组件性能很差。你如果用 vscode 开发,就会发现直接跑的话,cpu 负载一直很高,即使什么也没做

    所以用 gunicorn 这种中间件,设置一下配置文件之后,让多个 flask app 挂靠在 gunicorn 上就可以了

    不过只用 gunicorn,又会出现如果有多个 gunicorn,你要配置不同的端口,访问的时候就麻烦了。所以可以在前面再套一个 nginx 反向代理,这样用户访问的时候也不用输端口了
    noahzh
        12
    noahzh  
       2020-07-21 18:59:27 +08:00
    就是把 http 请求翻译成 python 能识别的请求,楼上都没有说到点子上,生产环境不推荐的原因是,无论你请求多小,你要保证的是任何时候请求来了能处理.werkzeug 只是一个满足功能的开发工具,但是没有任何人能保证他的可用性.
    julyclyde
        13
    julyclyde  
       2020-07-22 10:44:58 +08:00
    @volvo007 django 也是“被”调用的资格啊。和 flask 一样的
    mywaiting
        14
    mywaiting  
       2020-07-22 11:01:25 +08:00
    Tornado 就没有这个困扰,自身就是生产环境的 Server 的实现(当然也有兼容 WSGI 的实现)

    性能还相当不错,典型的放心去爱良心产品
    ruanimal
        15
    ruanimal  
       2020-07-22 14:23:39 +08:00
    @volvo007 为啥有“多个 gunicorn”,gunicorn 可以多进程啊
    SenLief
        16
    SenLief  
       2020-07-22 15:18:11 +08:00
    gunicorn 是个不错的工具,不过这个无法在 windows 上跑,我看 flask 官方快速开始文档使用了 waitress,纯 py 实现的 wsgi 框架也还蛮好用的。
    volvo007
        17
    volvo007  
       2020-07-22 17:31:49 +08:00
    @ruanimal 其实这也是我没搞懂的一个地方。我这里说的多线程当然不是 worker 参数分配给每个 gunicorn 服务的线程数量;而是说如果我有两个完全不同的 site 需要部署,那我的理解是我需要跑两个 gunicorn 服务来将不同的 site 分离开

    但我并不清楚要这么做的最佳实践是什么……

    另一个常见情况是,有一个 /home 的入口,通过 /home 可以跳转到其他 app 比如 /func1, /func2 ;我现在做的办法比较蠢,就是一个 app 跑一个 gunicorn 服务,然后每个服务分配一个端口,再通过 nginx 反向代理访问。有没有办法把 多个 app 放到一个 gunicorn 服务下面跑呢?

    网上找了不少资料。当然可以通过在 main_app 里面 import app1, app2 来把 其他 app.py 里的东西拉过来搞;但很多也是直接运行多个 gunicorn 服务,没搞清楚这种情况的最佳实践是什么
    ruanimal
        18
    ruanimal  
       2020-07-23 10:18:59 +08:00   ❤️ 1
    @volvo007 你这个是分 app,flask 是用 blueprint 来做的 https://flask.palletsprojects.com/en/1.1.x/blueprints/

    部署的时候用一个 gunicorn 就好了
    volvo007
        19
    volvo007  
       2020-07-23 11:23:14 +08:00
    @ruanimal 多谢。搜了下例子,这个类的出发点解决了我的问题,不过现在还没办法自己写。回头练练
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4216 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 10:14 · PVG 18:14 · LAX 03:14 · JFK 06:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.