Nginx报502 Bad Gateway完整排查思路(PHP-FPM场景)
Nginx 出现 502 Bad Gateway 是最常见的报错之一,90% 的情况都是 PHP-FPM 出了问题。下面是完整的排查思路,按顺序一步步来,基本都能解决。
1. 先看 PHP-FPM 是否在运行
systemctl status php-fpm
如果显示 failed 或 inactive,直接重启:
systemctl restart php-fpm
注意:CentOS 7 一般是
php-fpm,Ubuntu 可能是php7.4-fpm之类的,看你装的版本。
2. 看 Nginx 错误日志(最关键)
tail -f /var/log/nginx/error.log
常见错误信息:
错误1:connect() failed (111: Connection refused) while connecting to upstream
说明 PHP-FPM 没启动,或者监听地址不对。
错误2:upstream timed out
PHP 脚本执行超时了,或者 PHP-FPM 进程不够用。
错误3:Primary script unknown
Nginx 配置里的 SCRIPT_FILENAME 路径不对,找不到 PHP 文件。
3. 检查 Nginx 配置是否正确
nginx -t
如果显示 test is successful 说明配置语法没问题。
重点检查 fastcgi_pass 这一行:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000; # 或者 unix:/run/php-fpm/www.sock
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
常见问题:
- fastcgi_pass 地址和 PHP-FPM 实际监听地址不一致
- SCRIPT_FILENAME 路径写错了
4. 检查 PHP-FPM 监听地址
netstat -tlnp | grep php-fpm
或者:
ss -tlnp | grep php-fpm
看 PHP-FPM 是监听在 9000 端口还是 unix sock 文件,然后和 Nginx 配置里的 fastcgi_pass 对应上。
5. 检查 PHP-FPM 进程数是否够
看 PHP-FPM 配置:
vi /etc/php-fpm.d/www.conf
重点参数:
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
如果访问量大,进程数不够就会 502。
6. 检查 PHP 错误日志
tail -f /var/log/php-fpm/www-error.log
有时候 PHP 代码本身报错,也会导致 502。
7. 其他常见原因
磁盘满了
df -h
内存不够
free -h
如果内存不足,PHP-FPM 进程会被杀掉,也会 502。
SELinux 没关
参考我之前的文章,关掉 SELinux 试试。
排查顺序总结
- 重启 PHP-FPM → 看能不能恢复
- 看 Nginx 错误日志 → 定位具体错误
- 检查 Nginx 配置 → fastcgi_pass 和 SCRIPT_FILENAME
- 检查 PHP-FPM 状态 → 监听地址、进程数
- 检查系统资源 → 磁盘、内存
- 检查 SELinux
遇到服务器、Nginx、MySQL 报错,可以加微信远程协助排查问题。
PHP 性能优化:从代码到部署的完整指南
前言
PHP 性能优化是每个 PHP 开发者都绕不开的话题。很多人觉得 PHP 性能差,但实际上通过合理的优化,PHP 应用完全可以达到很高的性能水平。本文从代码层面到部署层面,带你完整梳理 PHP 性能优化的思路。
一、代码层面优化
1. 避免在循环中做数据库查询
// 慢:循环中查询数据库
foreach ($users as $user) {
$order = $db->query("SELECT * FROM orders WHERE user_id = {$user['id']}");
}
// 快:一次性查询,然后用数组映射
$userIds = array_column($users, 'id');
$orders = $db->query("SELECT * FROM orders WHERE user_id IN (" . implode(',', $userIds) . ")")->fetchAll();
$orderMap = array_column($orders, null, 'user_id');
2. 用生成器处理大数据
// 慢:一次性加载所有数据到内存
$users = $db->query("SELECT * FROM big_table")->fetchAll();
// 快:用生成器逐行处理
function getUsers() {
$stmt = $pdo->query("SELECT * FROM big_table");
while ($row = $stmt->fetch()) {
yield $row;
}
}
3. 字符串拼接 vs implode
// 慢:频繁拼接字符串
$str = '';
foreach ($items as $item) {
$str .= $item . ',';
}
// 快:用数组收集最后拼接
$parts = [];
foreach ($items as $item) {
$parts[] = $item;
}
$str = implode(',', $parts);
二、PHP 配置优化
1. OPcache 必开
OPcache 是 PHP 性能提升最大的一个扩展,没有之一。
; php.ini
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
开启 OPcache 后,PHP 脚本会被编译成字节码缓存起来,避免每次请求都重新编译。性能提升通常在 2-5 倍。
2. 合理设置内存限制
memory_limit = 256M
不要设置太大,也不要太小。根据你的应用实际情况调整。
三、数据库优化
1. 开启慢查询日志
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
找出慢查询,然后针对性优化。
2. 使用持久化连接要谨慎
// 不一定更快,可能反而更慢
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass', [
PDO::ATTR_PERSISTENT => true
]);
持久化连接在高并发场景下可能导致连接耗尽,要根据实际情况测试。
四、部署层面优化
1. 使用 PHP-FPM 优化
; php-fpm/www.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
根据服务器内存调整 max_children,每个 PHP-FPM 进程大约占用 20-40MB 内存。
2. Nginx 开启 gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
3. 静态文件 CDN 加速
把图片、CSS、JS 等静态资源放到 CDN 上,减轻服务器压力。
五、性能监控工具
- Xdebug:代码性能分析,找出瓶颈函数
- Blackfire:更专业的性能分析工具
- New Relic:APM 应用性能监控
- ab / wrk:压力测试工具
总结
PHP 性能优化的核心思路:
- 先找出瓶颈在哪里,不要盲目优化
- 代码层面:减少数据库查询、减少内存占用
- 配置层面:OPcache 必开
- 部署层面:PHP-FPM、Nginx、数据库都要调优
- 用工具量化优化效果
性能优化是一个持续迭代的过程,不要指望一次性优化到位。每次做一点,慢慢积累。