Google Cloud Run搭配php-fpm冷启动出现502 Bad Gateway(socket未找到)问题
问题根因
supervisord默认会并行启动所有配置的进程,nginx的启动速度远快于php-fpm。Google Cloud Run的实例冷启动后,首次请求或健康检查到达时,php-fpm还未完成启动流程,对应的Unix套接字文件/run/php/php7.4-fpm.sock尚未生成,因此nginx返回502错误。等待数秒后php-fpm启动完成、套接字文件生成,第二次请求即可正常响应。
可行解决方案
方案1:调整supervisord启动优先级
修改supervisord配置,通过priority参数控制启动顺序,确保php-fpm优先启动,同时设置启动等待时间确认进程正常运行:
[supervisord] nodaemon=true user=root [program:php-fpm] command=php-fpm stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 priority=100 ; 数值越小优先级越高,优先启动 startsecs=2 ; 启动后等待2秒确认进程无异常退出 [program:nginx] command=nginx -g "daemon off;" stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 priority=200 ; 优先级低于php-fpm,后启动 startsecs=1
方案2:entrypoint添加套接字等待逻辑
在entrypoint.sh中增加等待判断,直到php-fpm套接字生成后再完成实例启动,避免Cloud Run提前将流量切到未就绪的实例:
else # 后台启动supervisord /usr/bin/supervisord & SOCK_PATH="/run/php/php7.4-fpm.sock" # 最多等待10秒直到套接字生成 for i in {1..20}; do if [ -S "$SOCK_PATH" ]; then break fi sleep 0.5 done # 前台挂载supervisord进程 wait $! fi
方案3:替换为TCP通信(可选)
如果不想处理Unix套接字的生成时序问题,可以将php-fpm与nginx的通信方式改为TCP,容错性更高:
- 修改php-fpm自定义配置:
[global] daemonize = no [www] listen = 127.0.0.1:9000 listen.owner = www-data listen.group = www-data listen.mode = 0660
- 修改nginx.conf中对应配置:
fastcgi_pass 127.0.0.1:9000;
额外优化建议
entrypoint.sh中执行的php artisan migrate会拉长实例冷启动时间,建议将数据库迁移操作放到部署流水线中执行,不要放在实例启动逻辑内,进一步降低冷启动耗时。
内容的提问来源于stack exchange,提问作者FooBar
相关产品推荐
相关产品推荐

