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

Python Web 项目的部署如此之复杂!

  •  
  •   sadfQED2 · 357 天前 · 3339 次点击
    这是一个创建于 357 天前的主题,其中的信息可能已经有所发展或是发生改变。

    接手了一个 python django 写的上古项目。今天稍稍改了改,部署上线的时候突然看到启动命令竟然写的是python manage.py runserver

    虽然我从来没写过 django 项目,但是我也知道这命令启动的是开发测试服务器。就跟前端的npm run dev一样。此时我内心”这特么怎么行,线上业务啊,怎么能这么敷衍,跑个测试服务器就上线“。于是想着改改 Dockerfile ,改成正经的线上部署。

    可是我也没搞过 django 啊,经过一通搜索,大致了解到,django 可以通过 Gunicon 、uWSGI 、Apache mod_wsgi 、Daphne 、Hypercom 、Uvicom 等等方式部署。我淦,怎么这么多啊,我也不知道选哪个啊,uWSGI 在官网写在第一个的,那就他吧。

    照着官网示例抄吧,先这样再那样,Dockerfile 改好了,试一试,草,Docker 容器怎么启动就停了?一通排查,原来 uwsgi --ini uwsgi.ini这命令不是前台运行的,Dockerfile 里面拿这个当启动命令起来立马就没了。

    经过 N 久翻阅文档,发现 uwsgi 启动会生成一个 pid 文件,看到这里,我这个大聪明有办法了,于是 Dockerfile 启动命令改成CMD uwsgi --ini uwsgi.ini && tail -f uwsgi.pid ,再次尝试,容器成功保活。

    正在得意我的聪明才智的时候,结果一看,我淦,uwsgi 是起来了,但是服务为啥不能用啊。又一通排查,我淦,uwsgi.ini 里面的路径好像有问题,可这玩意路径写到哪里文档也没说啊,网上一会说是项目路径,一会说是 app 路径,什么鬼啊,一个一个尝试,结果都特么不行。

    再仔细翻翻文档,这什么玩意呀,部署上线什么还要带个 sqllite 文件呀,怎么还有先执行命令整理代码啊,怎么还要。。。。。

    从早上 10 点一直捣鼓到现在晚上 8 点,饭都没吃饱,这什么破玩意啊。md 果断敲下 git reset -hard 。滚 tm 的,我真是吃饱了没事干,服务跑得好好的,改什么改,前人用开发服务器肯定是有他的道理的,瞎改什么改。就算服务挂了,Docker 容器自动拉起,有毛线关系啊。

    不得不感叹,我部署过上古时期的 java 项目,拷个 war 包上线。也部署过 php 项目,拷份代码到目录就上线,也部署过 golang 项目,本地交叉编译拷个二进制文件上线,也部署过 c c++项目... 像 python 这么恶心的还是第一次,什么乱七八糟路径,调试又没日志,找到日志又不清不楚的,没人用这玩意果然是有原因的。

    43 条回复    2024-02-06 11:27:57 +08:00
    yakun4566
        1
    yakun4566  
       357 天前
    python *.py 还好吧,我们线上项目 Java 也是 java -jar 啊(也有可能是我们水分太大
    volvo007
        2
    volvo007  
       357 天前
    op 好惨,上来选了个最“基础” 的…… 选 gunicorn 可破,但是,光选中间件也不行啊,你还没部署 nginx 反向代理呢 (狗头
    shimada666
        3
    shimada666  
       357 天前   ❤️ 2
    搞那么麻烦干嘛,直接 python manage.py runserver 就好了。
    等 qps 过 20 再考虑别的吧
    arischow
        4
    arischow  
       356 天前 via iPhone   ❤️ 7
    你接手的代码烂,你也菜😄
    llsquaer
        5
    llsquaer  
       356 天前
    写的 api 接口,直接 python manage.py runserver 没毛病。。工作期间 8 小时内 平均 QPS 80 左右至今没问题。内部使用。

    不过 python web 是略显复杂。主要就几个容器的区别。熟悉一个当万金油用
    sadfQED2
        6
    sadfQED2  
    OP
       356 天前 via Android
    @shimada666 线上大几十台机器,你说 qps 过 20 不

    @llsquaer 直接 runserver 区别大吗?是一个 ai 模型,为了提供 api 调用,就 django 包了一层,整个项目就一个接口,代码不超过 100 行
    ihmily
        7
    ihmily  
       356 天前
    项目就一个接口,直接使用 fastapi 就好了
    JiaNa
        8
    JiaNa  
       356 天前 via iPhone
    @sadfQED2 既然你说了是旧项目,如果之前没有出现性能问题,那么没有性能问题。
    如果你愿意折腾、学东西,模拟生产环境 API 进行压测,比较不同方式的性能区别。
    shimada666
        9
    shimada666  
       356 天前
    @sadfQED2 完全没问题,容器挂个 restart=always ,崩了还能重新启动
    sadfQED2
        10
    sadfQED2  
    OP
       356 天前
    @JiaNa 线上服务,不能随便压。我也不是专业运维,也不是专业的 python 开发。但是就我的理解,直接 python runserver 这应该是单进程运行的,就 python 来说这应该完全没办法充分利用 cpu 。

    但是这个项目本质上是调用 PyTorch ,PyTorch 底层又是调用 C++模块,C++模块是不是就能不受限于 Pyton 的单进程直接跑满 CPU 了我也不清楚。

    所以到底能不能充分利用 cpu 我也搞不清楚。
    sadfQED2
        11
    sadfQED2  
    OP
       356 天前
    @shimada666 #9 现在容器就是 restart=always ,然后上层网关配置了故障转移。某次请求失败会自动转到其他机房的容器上。但是想着 python runserver 还监听代码变化,随时重启,心里就觉得不舒服
    RedisMasterNode
        12
    RedisMasterNode  
       356 天前
    感觉不是语言的问题。不太理解,这些东西不是在 README 里面写好就行了吗?

    https://images2.imgbox.com/91/09/qF1P6Xv1_o.png

    这是自己写的古老的新人项目,入职第一周做的,要怎么运行写好就是了,python 也是一样的。

    所以骂 python 没用,python 也有一样轻轻松松启动的项目,要怪就怪你这个同事。我运行 java 项目也摸索了很久不知道要怎么启动,c++ 也是各种依赖问题,说白了就是还菜(没有贬义,每个人都有新学东西的时候),还没入门,接手了不熟悉的语言就要运行要调试了,心态放好点都不至于这样。
    chenqh
        13
    chenqh  
       356 天前
    因为 python 有 gil,所以 djanog runserver 就可以了啊,gunicorn 用进程模型的话,就相当于 master 负责起多个进程
    chenqh
        14
    chenqh  
       356 天前
    python 像 tornado 想要利用多核,就是 supervisor 起多个进程,模型更简单粗暴
    wizardyhnr
        15
    wizardyhnr  
       356 天前
    uwsgi+nginx+django 部署本来就是配置多个服务,这种多进程通信 debug 就很难了。楼主还选 docker 容器,docker 推荐一个容器一个服务,一个容器部署多个服务可能很多坑。楼主属于踩坑体质吧?
    msg7086
        16
    msg7086  
       356 天前
    下次你试试看部署一下那种 2000 年前后写的带汇编的 C 项目到现代的平台。才折腾一天叫什么复杂。
    光是把内嵌的 MMX 和 3dnow!汇编全部重写成 SSE/AVX 就得花掉你几星期(笑)
    biaodianfu
        17
    biaodianfu  
       356 天前   ❤️ 1
    Django 没接触,不知道怎么部署还情有可原,Linux 命令也不熟悉,才得意自己的聪明才智,即使不知道使用 supervisor 守护进程,也应该知道使用 nohup 命令让程序不挂起。
    wenrouxiaozhu
        18
    wenrouxiaozhu  
       356 天前
    @sadfQED2 用 Gunicon 吧👀...觉得“runserver 监听代码变化,随时重启,心里就觉得不舒服” ,可以后面加一个--noreload 😂
    elboble
        19
    elboble  
       356 天前
    是略烦,反正 supervisor+uwsgi+nginx+django ,搞过一次就行了,路径什么的,的确文档说的不清楚,每次都是对着原来的例子改的。
    dayeye2006199
        20
    dayeye2006199  
       356 天前
    chatgpt 糊个 dockerfile 很快的
    tfdetang
        21
    tfdetang  
       356 天前
    @sadfQED2 ai 模型直接 runserver 会阻塞吧,并发请求还是会有问题的;
    如果这种场景最好还是用 fastapi ; 可以找个 uvicorn + fastapi + docker 的模板项目改改就行了;
    当然现在这样也不是不能用
    sadfQED2
        22
    sadfQED2  
    OP
       356 天前 via Android
    @tfdetang 啊?会阻塞吗?我等会试试,现在一次推理也就十多二十毫秒,可能机器够多,负载均衡后一直没发现问题

    fastapi 能简单一点?你别忽悠我,我部署这玩意已经恶心吐了,换一个等会我又几天搞不出来。主要是这破玩意还要 GPU ,然后走公司部署系统又必须要 Dockerfile ,在 docker 里面搞显卡驱动 cuda 啥的我已经吐了
    sadfQED2
        23
    sadfQED2  
    OP
       356 天前 via Android
    @tfdetang 我测试了一下,不会阻筛,两个请求是并行的
    nevermoreluo
        24
    nevermoreluo  
       356 天前
    哈哈哈哈哈 确实挺复杂的
    去年闲时捡起了很多年前 python ,随便折腾也折腾了一下午 docker+uwsgi+django
    https://github.com/nevermoreluo/kitchen/blob/main/docker-compose.yml
    祝你好运吧
    chenqh
        25
    chenqh  
       356 天前
    @sadfQED2 汗了,django 单进程,同步肯定阻塞啊,你不信,就去 sleep 看一下,就知道了,一般而已 python 要部署多个实例,
    在 docker 之前就是用 supervisor 起多个进程, docker 时代应该是起多个实例
    sadfQED2
        26
    sadfQED2  
    OP
       356 天前 via Android
    @chenqh 我就是 sleep 测试的,sleep10 秒,同时发两个请求,两个都 10s 后正常返回
    chenqh
        27
    chenqh  
       356 天前
    @sadfQED2 你不会是起了多个 docker 实例吧,还是说我的理解有问题?
    sadfQED2
        28
    sadfQED2  
    OP
       356 天前
    @chenqh #27
    ```
    re_path("sleep",data.sleep)

    def sleep(request):
    time.sleep(10)
    return HttpResponse(json.dumps({
    "status": 1,
    }))
    ```

    python manage.py runserver 启动

    开 2 个命令行,同时 curl 127.0.0.1:8000/sleep ,两个请求都是 10s 后同时返回
    chenqh
        29
    chenqh  
       356 天前   ❤️ 1
    chenqh
        30
    chenqh  
       356 天前
    @sadfQED2 我的,我用 tornado 来理解 django 了
    KJR5OR04CnCiWf02
        31
    KJR5OR04CnCiWf02  
       356 天前
    楼主在做什么 ai 应用?感觉是个大怨种。
    XxxxD
        32
    XxxxD  
       356 天前
    uwsgi 文档感觉好久都没更新,可以 youtube 搜下搭配 Gunicorn 部署
    fantathat
        33
    fantathat  
       356 天前
    确实复杂,用 gunicorn 涉及到 wsgi, 需要导出 application?
    iorilu
        34
    iorilu  
       355 天前
    生成环境不要设折腾, 只要能跑就不要动
    IurNusRay
        35
    IurNusRay  
       355 天前
    你的 uwsgi.ini 文件是不是配置了 daemonize , 这种模式 uwsgi 主进程开启子进程后会退出,于是 docker 容器也会停止,改成 logto 就可以
    tfdetang
        36
    tfdetang  
       355 天前
    @sadfQED2 看来 django 默认开启了多线程; 其实 docker 里不用搞显卡驱动啥的,base 镜像直接用 torch 啥的官方 gpu 版本的镜像,后面只要把 python 的部分搞定就行了
    sanzrolee
        37
    sanzrolee  
       355 天前
    uvicom + supervisor 嘎嘎香,再套层 docker 容器在最外层也可以。
    julyclyde
        38
    julyclyde  
       354 天前
    uwsgi 难道没有“前台运行”功能吗?
    干嘛用 tail 来保活?

    那你用了 tail ,将来运行 docker kill 的时候,你让 tail 命令去被 kill 么?
    julyclyde
        39
    julyclyde  
       354 天前
    你想要的那种“只上传应用程序本身,但是不管运行机制”其实在 python 世界也是存在的
    就是 google appengine 、sina appengine 、heroku 那一类

    python 、nodejs 、java 比较像,都是“由该语言本身写一个服务器”来运行自己
    julyclyde
        40
    julyclyde  
       354 天前
    还有,如果你们的数据库是 sqlite ,将来可能扩容到多实例的时候会遇到问题
    julyclyde
        41
    julyclyde  
       354 天前
    @sadfQED2 大几十台机器不一定过 20 啊
    你知道不,东南亚某知名电子商务网站,在 99 大促销的时候,曾经有关键组件“高达四十八 QPS”,比平时翻两番呢

    你 AI 模型的运行速度,浏览器能等得了么?回头估计还得加个 celery
    Maerd
        42
    Maerd  
       349 天前
    比较好奇 一个接口为什么要用 django,而不是用更方便的 fastapi
    Xs2y6914BljWqNfl
        43
    Xs2y6914BljWqNfl  
       301 天前
    @Maerd 完全看个人喜好的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1092 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 19:15 · PVG 03:15 · LAX 11:15 · JFK 14:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.