V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
dzdh
V2EX  ›  问与答

聊聊 PHP 容器应用的最佳实践

  •  
  •   dzdh · 175 天前 · 1850 次点击
    这是一个创建于 175 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近公司正在推进容器化建设,主要是扩容方便。
    然后有几个问题,问一下。

    项目是 laravel 。那么附带的还有他的 queue 和 cron artisan schedule:run 。

    是都放在一个容器里吗?弄个 supervisor 启动 nginx 、fpm 、cron -f 、和 queue:work ?

    总觉得哪里不对,有啥最佳实践推荐一下吗?
    35 条回复    2022-08-17 12:16:17 +08:00
    cooper
        1
    cooper  
       175 天前
    我们就是一个 docker 中,没啥不好。已经用三年了。
    XiLingHost
        2
    XiLingHost  
       175 天前
    ss098
        3
    ss098  
       175 天前
    可以构建成一个容器,但不要在一个容器内使用 supervisor 或其他进程管理工具启动,要作为多个容器启动。
    dzdh
        4
    dzdh  
    OP
       175 天前
    @ss098

    emmm.. 构建成 1 个容器 .... 多个容器启动。 啥。

    一个 image ,根据参数启动不同的进程作为独立 container 是吧。
    shoaly
        5
    shoaly  
       175 天前
    @XiLingHost 这个是啥? readme 里面光做了一个 logo , 有点蒙蒙的
    LexLuth0r
        6
    LexLuth0r  
       175 天前
    一个 Pod 中启动多个 container ,如 nginx 、php-fpm 服务、queue 服务。如果 queue 启动较多防止单个 Pod 资源不足,queue 服务也可以单独部署在一个 Pod 中,cron 同理。如果某一个 container 会频繁扩容就单独放到一个 Pod 中方便增加副本数。
    dzdh
        7
    dzdh  
    OP
       175 天前
    @LexLuth0r 不是 k8s 呢
    zyh94946
        8
    zyh94946  
       175 天前
    不是 k8s 用什么?
    xuelu520
        9
    xuelu520  
       175 天前
    我们的 laravel 项目,queue 和 console 的脚本都有单独的容器来。
    Rache1
        10
    Rache1  
       175 天前
    镜像都是同一个,queue 和 schedule 这些可以放到一个单独的容器里面去跑,使用 queue 使用 supervisor 守护
    dusu
        11
    dusu  
       175 天前 via iPhone
    肯定拆开来用 docker compose
    redis mysql 这种放一个容器
    升级起来不是要命么
    而且基本上他们升级频率不高吧

    另外 简单说两个坑 可自行试试
    1. network 如果用 bridge ,性能可能会比裸跑低 30%
    2. 不用 volume ,用挂载代码,性能可能会比裸跑扣一半以上
    dusu
        12
    dusu  
       175 天前 via iPhone
    @dusu 哦 看错了 没有 redis/mysql😥
    nginx 的话基本上看业务会不会后期扩展了
    如果会就拆出来 如果不考虑就放一块
    queue 和 cron 可以考虑同镜像不同容器
    DrX
        13
    DrX  
       175 天前
    说一下我的做法,目前感觉用起来非常舒服:

    web 一个容器,里面用 supervisor 同时跑 nginx + php-fpm
    queue 、cron 单独一个容器

    #3 三楼所说的「不要在一个容器内使用 supervisor 」不适用于传统 php 项目
    leo108
        14
    leo108  
       175 天前
    #13 传统 PHP 项目也是可以把 PHP 和 Nginx 拆开成两个容器的
    shuimugan
        15
    shuimugan  
       175 天前 via Android
    上 nginx unit 就可以把 php 和 nginx 二合一了
    goodSleep
        16
    goodSleep  
       175 天前 via Android
    我们没用容器,但是 artisan queue supervisor 都是单独部了一套业务
    dzdh
        17
    dzdh  
    OP
       175 天前
    @shuimugan #14 一直没研究明白这个东西。这个东西没有配置文件。必须只能是 http post 配置然后存在内存里吗?
    dzdh
        18
    dzdh  
    OP
       175 天前
    @dusu #11

    compose 一个 service 的存储是共享的吗?
    reter
        19
    reter  
       175 天前
    没有人规定容器里面不能使用 supervisor 。

    但是容器只能监控第一个启动进程,如果使用了 supervisor ,那么容器监控到的是 supervisor 状态,而不是具体服务的状态。
    在容器内使用 supervisor 带来比较明显的缺点:
    - 进程监控( docker 只能看到 supervisor 的存在,无法感知 supervisor 背后启动的服务, 比如 docker ps )
    - 日志管理(如果服务直接往 stdout 输出日志,日期可以被 docker 收集,如果加了 supervisor 显然不能直接收集)
    - 信号处理+服务重启 (docker 重启服务时,会先向进程发送信号 SIGTERM ,此时服务可进行后续处理,超时才发送 SIGKILL. 使用 supervisor 可能需要进行额外配置,同时重启 supervisor 会将后面所有的服务都重启)

    同时一个服务一个容器,可以很好的利用现有的容器监控方案,然而使用 supervisor 就失去了这些优势。

    没有人规定容器里面不能使用 supervisor 。
    DrX
        20
    DrX  
       175 天前
    @leo108
    #14
    分是能分,但是呢,传统 php 项目经常在 nginx 、fpm 共用 public 文件目录的。

    典型情况是 fpm 保存文件到 public/uploads 目录,nginx 提供静态文件服务,分开了会很麻烦。
    XiLingHost
        21
    XiLingHost  
       175 天前
    @shoaly 这就是一个基于 docker 的 php laravel 项目
    gesse
        22
    gesse  
       175 天前
    容器里应该少用 supervisor ,用 s6 多
    iyaozhen
        23
    iyaozhen  
       175 天前
    容器里面不要用 supervisor ,挂了就让容器自己重启

    nginx 可以放进去,但应该轻量点,只是本地和 php 配合,把更多的功能做到网关层

    cron 啥的单独建集群和接受 http 请求的分开
    superchijinpeng
        24
    superchijinpeng  
       175 天前
    拆到多个容器中
    superchijinpeng
        25
    superchijinpeng  
       175 天前
    富容器没有意义
    toomoy
        26
    toomoy  
       175 天前
    https://github.com/imbossa/docker_dev
    这个就包含 supervisor
    luyaolu
        27
    luyaolu  
       175 天前
    我现在的就是一个 docker 中 大半年了 没啥问题
    shuimugan
        28
    shuimugan  
       175 天前
    @dzdh nginx unit 说白了就是更容易编程化的 nginx ,你也可以把 json 写到文件,然后给 post json 文件的 curl 命令做个 alias ,就能达到修改配置文件 + nginx -s reload 的效果
    dzdh
        29
    dzdh  
    OP
       175 天前
    @shuimugan #28 那我的配置一辈子不变就不能直接读取个文件吗? docker file 也好写啊

    CMD ["unitd","-c","/etc/service.json"] 他不香吗。。。。
    dzdh
        30
    dzdh  
    OP
       175 天前
    @shuimugan 我在容器里为啥要 reload 啊
    xiaochong0302
        31
    xiaochong0302  
       175 天前
    酷瓜云课堂的实践: https://gitee.com/koogua/course-tencent-cloud-docker

    php + cron + workerman (supervisor)
    nginx
    mysql
    redis
    xunsearch
    wangningkai
        32
    wangningkai  
       175 天前 via iPhone
    GitHub 搜 dnmp ,用 docker- compose 编排
    shuimugan
        33
    shuimugan  
       175 天前
    @dzdh 我觉得主要看你们是否把调整配置当成一次发版(更新容器)进行操作,如果不会线上 reload 那的确可以直接单个文件一把梭。

    reload 用于一般用于蓝绿部署,nginx unit 的条件路由可以很好的控制流量,比如通过特定 header 字段和值进行流量切换,比如把测试账号引流到特定节点。

    另外不建议把 nginx 和 php-fpm 分开部署,因为 php 的 curl 功能过于强大,如果代码逻辑不严谨或者缺乏安全团队测试,不恰当使用 curl 的话,会被和 gopher 组合构造出任意代码给 php-fpm 执行(相当于后门)。
    julyclyde
        34
    julyclyde  
       174 天前
    在容器内就没必要 supervisord 或者 systemd 了

    该出错的时候能正确的出错,是一种较佳实践
    julyclyde
        35
    julyclyde  
       174 天前
    @shuimugan 换个说法就是,把容器当作短期的“运行”还是当作长期的“机器”
    如果是后者,各种操作产生的结果会累积起来形成状态,这个状态不一定是期望的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   实用小工具   ·   4672 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 50ms · UTC 01:33 · PVG 09:33 · LAX 17:33 · JFK 20:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.