You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让cgi-fcgi命令在状态码异常时失败?K8s PHP-FPM健康检查

实现PHP-FPM健康检查的状态码校验脚本

针对你的需求,这里提供两种可靠的实现方式,替代简单的grep检测,确保脚本能准确识别HTTP状态码并在非成功状态时返回失败退出码:

方法一:基于cgi-fcgi解析响应头提取状态码

修改原有脚本,捕获并解析PHP-FPM返回的Status响应头,判断状态码是否符合预期:

#!/usr/bin/env bash

# 定义FCGI请求环境变量
fcgi_env=(
  SCRIPT_NAME=/var/www/html/public/index.php
  SCRIPT_FILENAME=/var/www/html/public/index.php
  REMOTE_ADDR=127.0.0.1
  REQUEST_METHOD=GET
  REQUEST_URI="$1"
  PATH_INFO="$1"
)

# 执行FCGI请求,捕获标准输出和错误输出
response=$(env -i "${fcgi_env[@]}" cgi-fcgi -bind -connect 127.0.0.1:9000 2>&1)

# 从响应中提取HTTP状态码
status_code=$(echo "$response" | grep -E '^Status: [0-9]+' | awk '{print $2}')

# 处理无响应或响应异常的情况
if [ -z "$status_code" ]; then
  echo "ERROR: No valid response from PHP-FPM"
  exit 1
fi

# 判断状态码是否为成功范围(1xx/2xx)
if [ "$status_code" -gt 299 ]; then
  echo "ERROR: Request failed with status code $status_code"
  exit 1
fi

echo "SUCCESS: Request returned status code $status_code"
exit 0

关键逻辑说明:

  • 使用2>&1将stderr合并到stdout,避免PHP-FPM连接失败时错误信息无法被捕获
  • 通过正则匹配提取Status:开头行的数字状态码,确保解析准确性
  • 处理状态码为空的极端情况(如PHP-FPM进程挂掉、连接超时),直接返回失败
  • 状态码大于299时返回非0退出码,符合Kubernetes健康检查的失败判定逻辑

方法二:使用专用FCGI工具简化逻辑

如果系统中可以安装第三方工具,fcgi-client(部分发行版可通过libfcgi-bin包安装)能直接根据HTTP状态码返回对应退出码,实现类似curl --fail的效果:

#!/usr/bin/env bash

# 直接调用fcgi-client,成功返回0,非2xx状态返回非0
fcgi-client -f /var/www/html/public/index.php \
  -u 127.0.0.1:9000 \
  -e REQUEST_URI="$1" \
  -e PATH_INFO="$1" \
  -e REMOTE_ADDR=127.0.0.1 \
  -e REQUEST_METHOD=GET > /dev/null

exit $?

优势:

  • 无需手动解析响应头,工具内部已处理状态码判断
  • 输出更简洁,适合作为Kubernetes探针脚本

注意事项

  • 确保PHP-FPM配置允许127.0.0.1的连接(默认配置已支持)
  • 若健康检查使用特定路径而非index.php,需修改SCRIPT_NAME和SCRIPT_FILENAME为对应文件路径
  • Kubernetes的存活/就绪探针会以脚本退出码判断健康状态,0表示健康,非0表示不健康,完全匹配上述脚本的返回逻辑

内容的提问来源于stack exchange,提问作者The Fool

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 08:45:29