Dnmp中使用Supervisor监控php进程状态
docker
docker
字数统计: 1.2k(字)
阅读时长: 5(分)
Supervisor简介
Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。
它是通过fork/exec的方式把这些被管理的进程当作supervisor的子进程来启动,这样只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去即可。
也实现当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,可以选择是否自己启动和报警。supervisor还提供了一个功能,可以为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程。
事件背景
给公司用 docker 部署新的 dnmp 开发环境,想用 supervisor 实现对 php 进程和 swoole 进程的监控。但是部署了 dnmp 后,发现对于存活的 php 进程无法正确的监控到,始终报 fatal ,致命错误。

错误分析
在 dnmp 中,由于 supervisor 作为一个独立的容器存在,所以对于监控配置文件 supervisor/conf.d/php-fpm.ini 中运行的 php 命令并无法正常执行(因为只有在php容器中才可执行 php-cli 命令)。
所以,接下来的改写,目的就是吧 supervisor 移植到 php 容器中运行。
参考文献
已修改的配置下载:https://github.com/jefferyjob/dnmp_supervisor
配置修改过程
php的dockerfile改写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| ARG PHP_VERSION FROM ${PHP_VERSION}
ARG TZ ARG PHP_EXTENSIONS ARG CONTAINER_PACKAGE_URL
RUN if [ $CONTAINER_PACKAGE_URL ] ; then sed -i "s/dl-cdn.alpinelinux.org/${CONTAINER_PACKAGE_URL}/g" /etc/apk/repositories ; fi
COPY ./extensions /tmp/extensions WORKDIR /tmp/extensions RUN chmod +x install.sh \ && sh install.sh \ && rm -rf /tmp/extensions
ADD ./extensions/install-php-extensions /usr/local/bin/
RUN chmod uga+x /usr/local/bin/install-php-extensions
RUN apk update \ && apk upgrade \ && apk add supervisor \ && apk add bash \ && apk --no-cache add tzdata \ && cp "/usr/share/zoneinfo/$TZ" /etc/localtime \ && echo "$TZ" > /etc/timezone \ && rm -rf /var/cache/apk/*
RUN apk add gnu-libiconv libstdc++ --no-cache --repository http://${CONTAINER_PACKAGE_URL}/alpine/edge/community/ --allow-untrusted ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php
RUN curl -o /usr/bin/composer https://mirrors.aliyun.com/composer/composer.phar \ && chmod +x /usr/bin/composer ENV COMPOSER_HOME=/tmp/composer
RUN apk --no-cache add shadow && usermod -u 1000 www-data && groupmod -g 1000 www-data
WORKDIR /var/www
|
主要修改的内容是:
1 2 3 4 5 6 7 8
| RUN apk update \ && apk upgrade \ && apk add supervisor \ && apk add bash \ && apk --no-cache add tzdata \ && cp "/usr/share/zoneinfo/$TZ" /etc/localtime \ && echo "$TZ" > /etc/timezone \ && rm -rf /var/cache/apk/*
|
docker-composer中 php 的容器编排修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| php: build: context: ./services/php args: PHP_VERSION: php:7.4.7-fpm-alpine CONTAINER_PACKAGE_URL: mirrors.ustc.edu.cn PHP_EXTENSIONS: pdo_mysql,mysqli,mbstring,gd,curl,opcache,apcu,zip,opcache,redis,swoole TZ: "Asia/Tokyo" container_name: php ports: - "9001:9001" expose: - 9000 - 9001 - 5200 volumes: - ..:/var/www/:rw - ./services/php/php.ini:/usr/local/etc/php/php.ini:ro - ./services/php/php-fpm.conf:/usr/local/etc/php-fpm.d/www.conf:rw - ./logs/php:/var/log/php - ./data/composer:/tmp/composer - ./services/supervisor/supervisord.conf:/etc/supervisord.conf:rw - ./services/supervisor/conf.d:/etc/supervisor/conf.d:rw - ./logs/supervisor:/var/log/supervisor:rw restart: always command: - /bin/sh - -c - | supervisord -n -c /etc/supervisord.conf cap_add: - SYS_PTRACE environment: APP_ENV: "developer" networks: - default
|
主要增加了 9001:9001的端口映射,然后在容器内部通过 expose 暴露 9001 的端口。
在 volumes 里面映射了 supervisor 的相关配置文件。
在 command 中加入了supervisor启动脚本:
1 2 3 4 5
| command: - /bin/sh - -c - | supervisord -n -c /etc/supervisord.conf
|
修改supervisor对于php的监听配置
services/supervisor/conf.d/php-fpm.ini
1 2 3
| [program:php] command=/usr/local/bin/php -S 0.0.0.0:80 directory=/var/www/
|
然后重新 build 容器,最后 up 启动容器就成功了!
测试结果

总结
当前处理方式的弊端
本篇文章处理的方式是将 supervisor 安装进 php 容器中,然后运行命令 command=/usr/local/bin/php -S 0.0.0.0:80 来监听 php 的相关进程。
所以这样做的弊端就是,如果 php 的容器宕机后,由于 supervisor 存在于php容器中,那么 supervisor 也将无法使用,所以supervisor失去了他监控健康进程的意义。
基于当前的环境要求如何改写
可以将 supervisor 继续作为一个独立的容器运行,然后在配置文件command中,通过 docker exec - it xxx xx 等相关配置,来监听别的容器中的相关进程是否健康。