最近在一个 Nginx + PHP-FPM 的环境下部署 WordPress,访问网站时出现了 504 网关超时错误。经过一番排查和解决,最终网站恢复了正常。在这篇文章中,我将详细记录问题的解决过程,希望对遇到类似问题的朋友有所帮助。
1. 问题描述
WordPress 网站部署在一个 Nginx + PHP-FPM 的环境下。但是当访问网站时,页面长时间无响应,最后显示"504 Gateway Time-out"错误。
2. 问题排查
2.1 检查 Nginx 错误日志
首先,我检查了 Nginx 的错误日志,发现有大量类似下面的错误:
复制
vbscript
2023/06/08 15:30:45 [error] 1234#1234: *1 upstream timed out (110: Connection timed out) while connecting to upstream, client: xxx.xxx.xxx.xxx, server: example.com, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.1-fpm.sock", host: "example.com"
这个错误表明,Nginx 在尝试连接 PHP-FPM 的过程中超时了。
2.2 检查 PHP-FPM 服务状态
接下来,我检查了 PHP-FPM 的状态,使用命令 sudo systemctl status php8.1-fpm
,发现 PHP-FPM 服务是正常运行的。
2.3 检查 Nginx fastcgi 超时设置
然后,我怀疑可能是 Nginx 的 fastcgi 超时设置太短了。我检查了 Nginx 的配置文件 /etc/nginx/nginx.conf,发现 fastcgi 的超时设置如下:
复制
ini
fastcgi_connect_timeout 60s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
这些设置看起来是合理的,60秒的超时时间对于大多数请求来说应该足够了。
2.4 检查 PHP-FPM 进程数设置
最后,我怀疑可能是 PHP-FPM 的进程数太少,导致请求排队,超过了 Nginx 的超时时间。我检查了 PHP-FPM 的配置文件 /etc/php/8.1/fpm/pool.d/www.conf,发现 PM 设置如下:
ini
复制
ini
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
这个设置表明,PHP-FPM 的进程数是动态调整的,最多可以有5个进程,起始有2个进程,最少有1个空闲进程,最多有3个空闲进程。
考虑到网站的访问量,这个设置的进程数可能有点少。
2.5 检查 Nginx 配置文件
在检查 Nginx 配置文件时,我发现在多个地方定义了 fastcgi_index
指令,导致 Nginx 报错,无法启动。
具体来说,fastcgi_index
指令同时出现在以下两个文件中:
- /etc/nginx/snippets/fastcgi-php.conf
- /etc/nginx/sites-available/wordpress.conf
3. 问题解决
3.1 解决重复的 fastcgi_index
指令
为了解决重复的 fastcgi_index
指令问题,我决定在网站的配置文件 /etc/nginx/sites-available/wordpress.conf 中保留 fastcgi_index
指令,然后从 /etc/nginx/snippets/fastcgi-php.conf 文件中删除 fastcgi_index
指令。
修改完成后,我运行 sudo nginx -t
测试 Nginx 配置,确保没有错误。然后我运行 sudo systemctl reload nginx
重新加载 Nginx 配置。
3.2 调整 PHP-FPM 进程数设置
为了解决 504 网关超时问题,我调整了 PHP-FPM 的 PM 设置,增加了进程数:
复制
ini
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
调整后,PHP-FPM 最多可以有20个进程,起始有5个进程,最少有5个空闲进程,最多有10个空闲进程。这个设置应该能够满足更高的并发请求。
保存配置文件后,我重启了 PHP-FPM 服务:
复制
sudo systemctl restart php8.1-fpm
然后我再次访问网站,这次网站成功加载,没有再出现504错误。
4. 总结
造成 WordPress 出现 504 网关超时错误的原因可能有多种,在我这个案例中,主要原因是 PHP-FPM 的进程数设置太少,导致请求排队,超过了 Nginx 的 fastcgi 超时时间。此外,Nginx 配置文件中重复的 fastcgi_index
指令也导致了 Nginx 无法正常启动。
解决方法如下:
- 检查 Nginx 错误日志,定位问题
- 检查 PHP-FPM 服务状态
- 检查 Nginx fastcgi 超时设置
- 检查 PHP-FPM 进程数设置
- 检查 Nginx 配置文件,解决重复的
fastcgi_index
指令 - 调整 PHP-FPM 进程数设置,增加进程数
- 重启 PHP-FPM 服务,重新加载 Nginx 配置
在实际生产环境中,我们需要根据网站的访问量,合理设置 PHP-FPM 的进程数。同时也需要关注 Nginx 的 fastcgi 超时设置,确保其与 PHP-FPM 的处理能力相匹配。定期检查 Nginx 配置文件,避免出现重复的指令。
希望这篇文章对大家有所帮助。如果大家有任何问题或建议,欢迎在评论区交流。