- 時間久了很容易忘,這裏作個備份
- 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:從新打開日誌文件,用於文件太大須要備份時的場景,從新打開不會清空原來的文件
- SIGUSR2: 重啓fpm,包括master和worker,當配置文件更改時,則須要重啓fpm讓配置文件生效
- SIGQUIT: 平滑關閉fpm,worker處理完請求再退出
- SIGTERM/SIGINT: 強制關閉fpm,會影響當前正在處理的請求
多進程池配置形式
[global]
pid=run/php-fpm.pid
error_log=syslog
include=etc/php-fpm.d/*.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
[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
參考資料