关于 Python 项目的生产环境部署 - V2EX
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
mickerwx
V2EX    Python

关于 Python 项目的生产环境部署

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

    现实情况

    • 目前公司有很多个项目,其中涉及 django 和 fastapi 两种框架,以及一些大模型服务
    • 目前包管理是使用的 miniconda ,然后各个项目直接 nohup 部署在跑,生产加测试差不多有十几个服务
    • 服务器涉及公有云和私有云两种,差不多也有 10 来台,包括开发测试服务器、生产服务器、redis 服务器、lvs 服务器、数据库服务器等
    • 目前还有部分服务需要和 java 后端那边进行通信

    遇到的问题

    1. 服务太多管理与更新麻烦
    2. 使用 conda 进行环境管理,太多环境了,切换也很麻烦
    3. 多个服务使用 http 进行通信,耗时有点长

    想想问问各位大佬们你们的生产是怎么部署的

    1. 直接部署还是会使用 supervisor 或者 docker 或者 k8s 等
    2. 包管理是使用什么进行管理的 venv?conda?还是其他?
    3. 多服务之间的通信是 http 还是 rpc ?
    37 条回复    2024-11-21 09:51:53 +08:00
    ytmsdy
        1
    ytmsdy  
       343 天前
    使用用 docker-compose 跑就行了,然后在服务器上写 README 就行了
    neotheone2333
        2
    neotheone2333  
       343 天前
    1. docker(compose)
    2. pip+requirements.txt
    3. http(碰到性能问题最近准备迁移到 grpc)

    刚从运维手动启停服务( nohup )的模式切过来,目前跑了两个月了没啥问题。就是 Python 镜像有点大,华为云的小水管每次上传要花点时间
    mickerwx
        3
    mickerwx  
    OP
       343 天前
    @ytmsdy
    @neotheone2333 这么说的我也去拿 docker 跑项目试试 搞个测试环境先跑跑看
    xiaogu2014
        4
    xiaogu2014  
       343 天前
    1. 一般来说 docker 和 k8s 都会上。docker 负责打包 image 。不需要 care 环境依赖啥的。k8s 主要做服务部署编排。。
    2. poetry 比较多。
    3. 一般来说是 rpc.服务间通信

    以及针对你现在的问题:
    服务太多管理与更新麻烦-> 如果每个服务环境都相互独立就不不会麻烦了。
    使用 conda 进行环境管理-> 这个是在每个 docker image 里面建立不同的环境。所以不需要考虑环境切换的问题。
    多个服务使用 http 进行通信,耗时有点长-> 体感上耗时长的话,可能并不是 rpc 能解决的问题。考虑下服务之间数据传输的合理性以及考虑下其他方式?
    vZexc0m
        5
    vZexc0m  
       343 天前
    1.更新麻烦 ->可以选择 Jenkins 之类的做 CI/CD
    2.环境管理->docker 、podman
    3.http 进行通信内网还好把

    django 用 gunicorn 部署 fastapi 用 uvicorn 。用容器就不用关心什么环境问题了
    mickerwx
        6
    mickerwx  
    OP
       343 天前
    @xiaogu2014
    @vZexc0m ok 感谢两位大佬 docker 确实能省时省力 不过上 ci/cd 的话 要维护的东西太多了 他们的代码提交很不规范 应该是没办法实现了
    mickerwx
        7
    mickerwx  
    OP
       343 天前
    @xiaogu2014
    @vZexc0m
    @neotheone2333
    @ytmsdy

    还有个问题 你们有需要解决并发请求的吗 原本他们解决并发是同一套代码部署多个服务 使用 nginx 做负载均衡 后来我加了 celery ,把这些业务代码放 celery 跑
    xiaogu2014
        8
    xiaogu2014  
       343 天前
    看起来你们需一个架构师来把服务微服务化+建立一套完整的 cicd 流程。
    这个是一劳永逸的事情。之后别人只需要提交 pr. 等 review.合并。然后一键部署就好了。
    xiaogu2014
        9
    xiaogu2014  
       343 天前
    `还有个问题 你们有需要解决并发请求的吗 原本他们解决并发是同一套代码部署多个服务`
    这不就是 k8s 帮你干的事情吗。。服务自动扩容/横向/纵向扩容。。
    mickerwx
        10
    mickerwx  
    OP
       343 天前
    @xiaogu2014 唉 别提了 招架构师是不可能的了 除非我自己来搞 但是这种吃力不讨好的活儿 老板看不到 实属没必要
    mirrornighth
        11
    mirrornighth  
       343 天前
    10 多台机器 docker swarm 就够了
    mirrornighth
        12
    mirrornighth  
       343 天前
    1.docker swarm 或 k8s (一般 10 多台 swarm 就沟通)
    defunct9
        13
    defunct9  
       343 天前
    天天搞这些,k8s 是正解。
    Hstar
        14
    Hstar  
       343 天前
    开发环境用什么做包管理都行, pip/poetry/pipenv, 最后一定要导出一个 requirement.txt, 生产环境只用 pip+requirement.txt 极简. 因为在生产环境再装一个其他东西没必要且还会引入包依赖问题.
    vZexc0m
        15
    vZexc0m  
       343 天前
    @mickerwx #6 CI/CD 不复杂,可以研究下 一劳永逸的事情。自动就部署了。

    并发请求是啥意思?同一台机器上一个项目跑多个实例没多大意义。如果之前只是单线程部署的话,部署的时候启用多个工作线程就行了,django 还可以结合 gevent.具体看文档。
    mickerwx
        16
    mickerwx  
    OP
       343 天前
    @mirrornighth 我去瞅瞅这俩 看看能不能用起来
    mickerwx
        17
    mickerwx  
    OP
       343 天前
    @vZexc0m 确实是可以去研究一下 ci/cd 正好最近项目没有啥事情干
    mayi203
        18
    mayi203  
       343 天前
    我个人项目,一直是 docker-compose
    adoal
        19
    adoal  
       343 天前
    我建议是先用 systemd unit (首选,除非还要跑在 EoL 很多年的老发行版上)或者 supervisord / s6 / runit 之类的服务管理工具,把服务启停管起来再说,至少不要设备意外重启了后接到电话时哼哧哼哧远程登进去 nohup 。并且在这个过程中逐步梳理项目,学习一下 FSH 之类的基础知识和运维安全知识,养成服务器管理操作的好习惯。

    上容器当然也是一种可行的选择。不过把乱七八糟的东西装进容器,只是给屎浇一层巧克力壳,掩盖乱七八糟。
    neotheone2333
        20
    neotheone2333  
       343 天前
    @mickerwx 我们的并发是两套处理,普通 http 请求不必说,定时任务和异步 http 接口做法是:
    1. io 密集型的走 fastapi 的 BackgroundTask ,写法用 httpx 之类的库全部改成 async
    2. cpu 密集型的走的 celery worker

    如果还处理不过来就得加机器了
    mickerwx
        21
    mickerwx  
    OP
       343 天前
    @adoal 感谢建议 之前用过一段时间的 supervisord 奈何项目多 服务多管理起来确实不方便 主要也没有一个合格的项目经理和技术经理 代码随便提交 从来没有 review 领导今天说部署一个这个版本就要部署 明天要哪个版本就要部署那个
    skyrim61
        22
    skyrim61  
       343 天前
    使用 alpine 构建一个 django5 的 docker 镜像, 使用 docker-compose 来管理项目的启动,停止和重启. 使用上, 只要修改 docker-compose 中的环境变量即可, 然后就一键启动. 省事省心
    adoal
        23
    adoal  
       343 天前
    @mickerwx 那你们最需要解决的问题是工作过程的治理,把操作规范化,上 CI/CD ,至于用什么技术和系统来部署,都只是细节
    skyrim61
        24
    skyrim61  
       343 天前
    . /root/venv/bin/activate
    cd /xx/xx/${PROJECT_NAME} && gunicorn -b 127.0.0.1:8000 -w 2 --threads 4 --reload ${PROJECT_NAME}.wsgi &
    nginx -g 'daemon off;'

    容器启动脚本
    mickerwx
        25
    mickerwx  
    OP
       343 天前
    @adoal 问题是现在解决不了这个 我只是个小兵 没有任何话语权 只能在不给自己找麻烦的情况下 把手头工作尽量干好 问这些问题 之前在上一家公司 是有专业运维来搞这些的 来这边 后端要写 部署要管 运维要管 唉
    mickerwx
        26
    mickerwx  
    OP
       343 天前
    @skyrim61 ok 谢谢建议 我去梳理梳理这些 然后看看改咋搞
    adoal
        27
    adoal  
       343 天前
    @mickerwx 那……没话语权的话,你探索出来的部署手段,会不会也被人因为习惯了 nohup 而软抵制呢。
    mickerwx
        28
    mickerwx  
    OP
       343 天前
    @adoal 这个不会 因为是我写后端 我部署 所以这个就是为了方便自己
    julyclyde
        29
    julyclyde  
       343 天前
    1 首先 nohup 、supervisorD 、pm2.5 肯定是不对的。正确的做法是 systemd 或者容器。如果多实例应该容器+k8s
    2 如用容器,尽量小一点,venv 就挺好吧
    mickerwx
        30
    mickerwx  
    OP
       343 天前
    @julyclyde ok 感谢 决定先容器化 然后考虑上 k8s ci/cd
    Hopetree
        31
    Hopetree  
       342 天前
    一个项目一个 docker-compose ,容器里面使用 supervisor 管理进程,完美
    flmn
        32
    flmn  
       342 天前
    docker swarm
    ytmsdy
        33
    ytmsdy  
       342 天前
    @mickerwx 这个就涉及到程序底层逻辑的问题了。
    一般是先估计,有些定时任务,或者耗时比较长,实时性不高的计算就全部丢到队列里面去处理。
    并发什么的按照你说的服务器规模,基本上不用太需要考虑。
    把耗时长的请求给单独,异步返回就行了。
    ccc1924
        34
    ccc1924  
       339 天前
    我这儿老服务用的是 supervisor ,新服务用的是 docker-compose
    目前暂时没有动态扩容的需求,所以 docker compose 够用了

    建议做好容器化,以后上 k8s/kamal 都方便不少

    celery 和 nginx 负载均衡上没有很大的区别,如果是长时间跑的后台任务,使用 celery 会更合适
    mickerwx
        35
    mickerwx  
    OP
       339 天前
    @ccc1924 那如果上 docker 的话 celery 是另起一个 docker 还是放主程序一起起 工作进程你们准备怎么设置
    ccc1924
        36
    ccc1924  
       339 天前
    @mickerwx #35 另外起一个 docker
    tisswb
        37
    tisswb  
       322 天前
    我这边运维大概 10 多个服务,都是在 ubuntu 上运行,
    1.supervisor
    2.项目内包管理 pip ,python 版本管理 pyenv
    3.http 慢就 grpc
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     857 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 21:40 PVG 05:40 LAX 14:40 JFK 17:40
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86