- 时间久了很容易忘,这里做个备份
- FastCGI协议php语言的实现,可以高效处理来自web端的动态请求
- php-fpm维护一个或者多个php-cgi进程池,处理请求时不需要频繁创建进程
- 所以比传统的CGI协议要更高效
技术架构
- 单master - 多worker
- master
- 非阻塞,异步IO模型
- 负责管理worker进程(创建、销毁、检查健康状态等)、监听连接、处理管理员发出的信号、启动时间循环等。
- master进程执行的四个阶段
- cgi初始化:外部信号hook注册、sapi全局变量初始化等;
- php环境初始化:加载和解析php.ini,加载php模块等;
- php-fpm初始化:加载和解析php-fpm.conf,初始化进程池等;
- php-fpm执行阶段:fork worker进程和启动事件循坏等。
- worker
- 阻塞模型
- 负责接收请求,处理请求,请求结束返回。
创建worker进程的三种方式
- static: 创建固定数目的worker进程,减少频繁创建进程的开销。
- dynamic: 动态调整worker进程数量,初始时会创建最低数目的worker进程,创建的进程数最大不超过设置的阈值。
- ondemand: 按需创建,来一个请求创建一个,请求处理完,进程结束。
master处理的信号说明
- SIGUSR1:重新打开日志文件,用于文件太大需要备份时的场景,重新打开不会清空原来的文件
- kill -s USR1 master进程id
- SIGUSR2: 重启fpm,包括master和worker,当配置文件更改时,则需要重启fpm让配置文件生效
- SIGQUIT: 平滑关闭fpm,worker处理完请求再退出
- SIGTERM/SIGINT: 强制关闭fpm,会影响当前正在处理的请求
多进程池配置形式
- 全局配置文件: php-fpm.conf
[global] pid=run/php-fpm.pid error_log=syslog include=etc/php-fpm.d/*.conf
- 连接池1的配置文件: pool1.conf
[pool1] listen = 127.0.0.1:9000 listen.mode = 666 user = php-fpm group = php-fpm pm = dynamic pm.max_children = 50 pm.start_servers = 20 pm.min_spare_servers = 5 pm.max_spare_servers = 35 pm.max_requests = 500 rlimit_files = 1024
- 连接池2的配置文件: pool2.conf
[pool2] #listen = /tmp/php-fcgi.sock listen = 127.0.0.1:9001 listen.mode = 666 user = php-fpm group = php-fpm pm = dynamic pm.max_children = 50 pm.start_servers = 20 pm.min_spare_servers = 5 pm.max_spare_servers = 35 pm.max_requests = 500 rlimit_files = 1024
管理脚本
#!/bin/bash # ################################### # #@desc php-fpm进程管理 # #@date 2019-04-04 # #@author wadeyu # ################################## # master进程id保存路径 MASTER_PID_PATH=$PHP_HOME/var/run/php-fpm.pid # php-fpm命令 PHP_FPM_CMD=$PHP_HOME/sbin/php-fpm # 错误闪烁提醒 blinkRed(){ echo -e "\e[05m \e[1;31m $1 \e[0m" } # 错误提醒:red errorTip(){ echo -e "\e[1;31m $1 \e[0m" } # 正常提醒:blue normalTip(){ echo -e "\e[1;34m $1 \e[0m" } # 检查php-fpm配置是否正常 isCfgOk(){ $PHP_FPM_CMD -t if [[ $? -gt 0 ]]; then errorTip "配置文件异常,请检查php-fpm配置文件!" fi return $? } # php-fpm正在运行中的主进程数量 getMainFpmCnt(){ if [[ ! -e $MASTER_PID_PATH ]]; then return 0 fi local pid=`cat $MASTER_PID_PATH` local cnt=`ps -ef | grep php-fpm | awk -F ' ' '{print $2}' | grep $pid | wc -l` return $cnt } # 检查php-fpm进程状态 checkStatus(){ if [[ ! -e $MASTER_PID_PATH ]]; then errorTip "php-fpm 未运行(pid file not found)......" return 1 fi getMainFpmCnt local cnt=$? local sts=1 if [[ $cnt -eq 1 ]]; then normalTip "php-fpm 正在运行中......" sts=0 else errorTip "php-fpm 未运行......" fi return $sts } # 启动php-fpm startFpm(){ isCfgOk || exit 1 checkStatus && exit 2 normalTip "启动php-fpm进程......" $PHP_FPM_CMD checkStatus } # 停止php-fpm stopFpm(){ checkStatus if [[ $? -eq 1 ]]; then return 0 fi pid=`cat $MASTER_PID_PATH` normalTip "停止php-fpm进程......" kill -s QUIT $pid getMainFpmCnt local cnt=$? while [[ $cnt -gt 0 ]]; do sleep 1s getMainFpmCnt cnt=$? done normalTip "操作成功!" } # 重新加载配置 reloadFpm(){ checkStatus || exit 1 pid=`cat $MASTER_PID_PATH` kill -s USR2 $pid normalTip "reload信号已发出,等待一会儿配置生效" } case "$1" in start) startFpm ;; stop) stopFpm ;; reload) reloadFpm ;; restart) stopFpm startFpm ;; status) checkStatus ;; *) echo "Usage $0 {start|stop|reload|restart|status}" exit 99 esac
参考资料
- php-fpm.conf官方配置说明
- php-fpm的进程pool设置
- PHP源码分析 - PHP-FPM运行原理
- PHP-FPM源码分析
- php-fpm信号
- php-fpm服务启动脚本
- shell判断文件是否存在
- SHELL输出颜色和闪烁控制
来源:https://www.cnblogs.com/wadeyu/p/10704415.html