Nginx 故障排查
掌握 Nginx 服务器故障排查的方法和技巧
故障排查流程
当 Nginx 出现故障时,建议按照以下流程进行排查:
- 检查 Nginx 服务状态 - 确认 Nginx 是否正常运行
- 查看错误日志 - 分析 Nginx 错误日志,定位问题原因
- 检查配置文件 - 验证 Nginx 配置文件语法是否正确
- 测试网络连接 - 确认网络连接和端口是否正常
- 分析访问日志 - 查看访问日志,了解请求情况
- 测试配置变更 - 逐步测试配置变更,找出问题所在
- 重启服务 - 在必要时重启 Nginx 服务
检查 Nginx 服务状态
查看服务状态
# 使用 systemctl(Systemd)
sudo systemctl status nginx
# 使用 service(SysV)
sudo service nginx status
# 检查进程
ps aux | grep nginx
# 检查端口
netstat -tuln | grep nginx
ss -tuln | grep nginx
启动和重启服务
# 启动服务
sudo systemctl start nginx # Systemd
sudo service nginx start # SysV
# 重启服务
sudo systemctl restart nginx # Systemd
sudo service nginx restart # SysV
# 重新加载配置
sudo systemctl reload nginx # Systemd
sudo service nginx reload # SysV
# 使用 nginx 命令重新加载
nginx -s reload
查看 Nginx 日志
错误日志
# 查看错误日志
cat /var/log/nginx/error.log
# 实时查看错误日志
tail -f /var/log/nginx/error.log
# 查看最近的错误
tail -n 50 /var/log/nginx/error.log
# 搜索特定错误
grep "error" /var/log/nginx/error.log
grep "warn" /var/log/nginx/error.log
访问日志
# 查看访问日志
cat /var/log/nginx/access.log
# 实时查看访问日志
tail -f /var/log/nginx/access.log
# 查看最近的访问
tail -n 50 /var/log/nginx/access.log
# 搜索特定请求
grep "GET /api" /var/log/nginx/access.log
grep "404" /var/log/nginx/access.log
检查 Nginx 配置
测试配置语法
# 测试配置语法
nginx -t
# 测试特定配置文件
nginx -t -c /etc/nginx/nginx.conf
查看配置文件
# 查看主配置文件
cat /etc/nginx/nginx.conf
# 查看站点配置文件
ls -la /etc/nginx/conf.d/
cat /etc/nginx/conf.d/default.conf
# 查看所有配置文件
find /etc/nginx -name "*.conf" -exec cat {} \;
常见故障及解决方案
配置语法错误
症状:Nginx 无法启动或重新加载配置
解决方案:
- 使用
nginx -t检查配置语法 - 修复错误提示中指出的语法问题
- 重新加载配置:
nginx -s reload
端口被占用
症状:Nginx 启动失败,错误信息显示端口已被占用
解决方案:
- 查找占用端口的进程:
lsof -i :80或netstat -tuln | grep :80 - 终止占用端口的进程:
kill -9 [PID] - 或修改 Nginx 配置,使用不同的端口
- 重启 Nginx 服务
403 Forbidden 错误
症状:访问网站时返回 403 Forbidden 错误
解决方案:
- 检查文件权限:
ls -la /var/www/html - 设置正确的文件权限:
chown -R nginx:nginx /var/www/html - 检查 Nginx 配置中的访问控制规则
- 检查 SELinux 或 AppArmor 配置
- 检查目录索引设置:确保 index 指令包含正确的索引文件
- 检查 location 指令中的 deny 规则
404 Not Found 错误
症状:访问网站时返回 404 Not Found 错误
解决方案:
- 确认文件是否存在:
ls -la /var/www/html/path/to/file - 检查 Nginx 配置中的 root 或 alias 指令
- 检查 location 配置是否正确
- 检查 rewrite 规则是否正确
- 检查 try_files 指令配置:
location / { try_files $uri $uri/ =404; } - 检查服务器名称和端口配置
502 Bad Gateway 错误
症状:访问网站时返回 502 Bad Gateway 错误
解决方案:
- 检查后端服务器是否正常运行:
systemctl status backend-service - 检查 Nginx 配置中的 proxy_pass 指令是否正确
- 检查后端服务器端口是否正确:
netstat -tuln | grep backend-port - 检查网络连接是否正常:
ping backend-server和telnet backend-server backend-port - 检查后端服务器防火墙设置
- 检查 proxy_set_header 指令是否正确设置
503 Service Unavailable 错误
症状:访问网站时返回 503 Service Unavailable 错误
解决方案:
- 检查后端服务器是否正常运行
- 检查 Nginx 配置中的 upstream 配置是否正确
- 检查负载均衡配置是否正确
- 检查服务器资源使用情况:
top或htop - 检查 upstream 服务器的健康检查配置:
upstream backend { server backend1.example.com max_fails=3 fail_timeout=30s; server backend2.example.com max_fails=3 fail_timeout=30s; } - 检查是否启用了维护模式或限流
504 Gateway Timeout 错误
症状:访问网站时返回 504 Gateway Timeout 错误
解决方案:
- 检查后端服务器响应时间:
curl -o /dev/null -s -w "%{time_total}\n" http://backend-server - 调整 Nginx 代理超时设置:
proxy_connect_timeout 60; proxy_send_timeout 60; proxy_read_timeout 60; proxy_buffer_size 16k; proxy_buffers 4 64k; proxy_busy_buffers_size 128k; - 优化后端服务器性能
- 检查网络连接是否正常
- 考虑使用异步处理或队列系统处理长时间运行的请求
400 Bad Request 错误
症状:访问网站时返回 400 Bad Request 错误
解决方案:
- 检查请求 URL 是否正确
- 检查请求头是否正确
- 检查 Nginx 配置中的 client_max_body_size 设置
- 检查是否有无效的请求参数
401 Unauthorized 错误
症状:访问网站时返回 401 Unauthorized 错误
解决方案:
- 检查认证配置是否正确
- 确认用户名和密码是否正确
- 检查 auth_basic 指令配置
405 Method Not Allowed 错误
症状:访问网站时返回 405 Method Not Allowed 错误
解决方案:
- 检查请求方法是否被允许
- 检查 Nginx 配置中的 limit_except 指令
- 检查后端服务器是否支持该请求方法
413 Request Entity Too Large 错误
症状:上传文件时返回 413 Request Entity Too Large 错误
解决方案:
- 调整 Nginx 配置中的 client_max_body_size 设置:
http { client_max_body_size 10M; # 允许最大 10MB 的请求体 } - 同时调整后端服务器的相关设置
500 Internal Server Error 错误
症状:访问网站时返回 500 Internal Server Error 错误
解决方案:
- 查看 Nginx 错误日志:
tail -n 50 /var/log/nginx/error.log - 检查后端应用是否正常运行
- 检查后端应用日志
- 检查 Nginx 配置中的 fastcgi_pass 或 proxy_pass 指令
- 检查文件权限和路径
性能相关问题
服务器响应缓慢
症状:网站加载速度慢,响应时间长
解决方案:
- 检查服务器资源使用情况:
top、free -m、df -h - 优化 Nginx 配置,增加工作进程数和连接数:
worker_processes auto; # 自动设置为 CPU 核心数 worker_rlimit_nofile 65536; events { worker_connections 10240; use epoll; multi_accept on; } - 启用缓存和压缩:
http { # 启用 gzip 压缩 gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; gzip_comp_level 6; gzip_min_length 256; gzip_buffers 16 8k; # 启用浏览器缓存 location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 30d; add_header Cache-Control "public, max-age=2592000"; } } - 优化后端应用性能
- 考虑使用 CDN 加速静态资源
- 使用 nginx-extras 或 OpenResty 提供更多优化功能
- 监控并优化数据库查询性能
- 使用缓存系统如 Redis 或 Memcached
连接数过多
症状:Nginx 连接数达到上限,新连接被拒绝
解决方案:
- 增加 Nginx 连接数限制:
events { worker_connections 10240; } - 增加系统文件描述符限制:
# 在 /etc/security/limits.conf 中添加 nginx soft nofile 65536 nginx hard nofile 65536 # 在 /etc/sysctl.conf 中添加 fs.file-max = 65536 net.core.somaxconn = 4096 # 应用系统配置 sysctl -p - 启用连接限制,防止 DoS 攻击:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s; location / { limit_req zone=mylimit burst=20 nodelay; } - 调整 keepalive 设置:
keepalive_timeout 65; keepalive_requests 100;
内存使用过高
症状:Nginx 进程占用内存过高,导致服务器内存不足
解决方案:
- 检查 Nginx 工作进程数:避免设置过多工作进程
- 调整 worker_rlimit_nofile 设置
- 检查是否有内存泄漏的模块
- 优化缓存设置:减少缓存大小
- 使用
ps aux --sort=-%mem | grep nginx查看内存使用情况
CPU 使用率过高
症状:Nginx 进程占用 CPU 过高,导致服务器响应缓慢
解决方案:
- 检查是否有大量并发连接或请求
- 优化 Nginx 配置:调整 worker_processes 和 worker_connections
- 检查是否有复杂的正则表达式或重写规则
- 启用 gzip_static 模块,减少 CPU 压缩开销
- 使用
top -H -p [nginx-pid]查看具体线程 CPU 使用情况
SSL/TLS 相关问题
SSL 证书错误
症状:浏览器显示 SSL 证书错误
解决方案:
- 检查 SSL 证书是否过期:
openssl x509 -in server.crt -dates -noout - 确认证书配置正确:检查 ssl_certificate 和 ssl_certificate_key 指令是否指向正确的文件路径
- 验证证书链是否完整:使用
openssl verify -CAfile ca-bundle.crt server.crt - 检查证书文件权限:确保 Nginx 进程可以读取证书文件
- 如果使用自签名证书,考虑使用 Let's Encrypt 获取免费证书
- 检查证书域名是否匹配:确保证书包含当前访问的域名
HTTPS 连接失败
症状:无法建立 HTTPS 连接
解决方案:
- 检查 443 端口是否开放:
netstat -tuln | grep 443 - 检查防火墙配置,确保 443 端口已开放:
# 检查防火墙状态 firewall-cmd --state # 开放 443 端口 firewall-cmd --permanent --add-port=443/tcp # 重新加载防火墙配置 firewall-cmd --reload - 检查 SSL 配置是否正确:确保 ssl_protocols 和 ssl_ciphers 配置合理
- 查看 Nginx 错误日志,了解具体错误原因:
tail -n 50 /var/log/nginx/error.log - 测试 SSL 连接:使用
openssl s_client -connect example.com:443
SSL 握手失败
症状:SSL 握手过程失败,无法建立安全连接
解决方案:
- 检查 SSL 协议版本配置:确保支持客户端使用的 SSL/TLS 版本
- 检查密码套件配置:确保配置了客户端支持的密码套件
- 检查证书是否被客户端信任
- 使用
openssl s_client -connect example.com:443 -debug查看详细握手过程
SSL 会话重用失败
症状:SSL 会话无法重用,每次连接都需要重新握手
解决方案:
- 启用 SSL 会话缓存:
ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; - 检查 SSL 会话票证配置:
ssl_session_tickets on;
Let's Encrypt 证书自动续期失败
症状:Let's Encrypt 证书无法自动续期,导致证书过期
解决方案:
- 检查 crontab 配置:确保续期脚本已正确设置
- 手动运行续期命令:
certbot renew --dry-run - 检查域名解析是否正确:确保域名可以正常解析到服务器
- 检查防火墙设置:确保 80 端口可以正常访问(用于 HTTP-01 挑战)
- 查看续期日志:
tail -n 50 /var/log/letsencrypt/letsencrypt.log
高级故障排查
使用 strace 跟踪系统调用
# 跟踪 Nginx 进程
sudo strace -p [Nginx PID]
# 启动 Nginx 并跟踪
sudo strace -f nginx
# 跟踪特定系统调用
sudo strace -e open,read,write -p [Nginx PID]
# 输出到文件
sudo strace -o nginx.strace -p [Nginx PID]
使用 gdb 调试 Nginx
# 安装 gdb
sudo apt install gdb # Ubuntu/Debian
sudo yum install gdb # CentOS/RHEL
# 调试 Nginx 进程
sudo gdb -p [Nginx PID]
# 查看堆栈跟踪
(gdb) bt
# 查看变量值
(gdb) print variable_name
# 设置断点
(gdb) break function_name
# 继续执行
(gdb) continue
# 单步执行
(gdb) step
(gdb) next
使用 tcpdump 抓包
# 安装 tcpdump
sudo apt install tcpdump # Ubuntu/Debian
sudo yum install tcpdump # CentOS/RHEL
# 抓取 80 端口的流量
sudo tcpdump -i eth0 port 80 -w nginx.pcap
# 抓取 443 端口的 HTTPS 流量
sudo tcpdump -i eth0 port 443 -w nginx-ssl.pcap
# 抓取特定 IP 的流量
sudo tcpdump -i eth0 host 192.168.1.100 -w client.pcap
# 分析抓包文件
wireshark nginx.pcap
# 简单分析
sudo tcpdump -r nginx.pcap | head -n 50
使用 nginx-debug 调试
# 安装 nginx-debug 包(如果可用)
sudo apt install nginx-debug # Ubuntu/Debian
# 启动调试模式
sudo nginx-debug
# 查看详细日志
tail -f /var/log/nginx/error.log
使用 lsof 查看文件描述符
# 查看 Nginx 打开的文件
sudo lsof -p [Nginx PID]
# 查看 Nginx 监听的端口
sudo lsof -i -P -n | grep nginx
# 查看所有打开的日志文件
sudo lsof | grep nginx | grep log
使用 netstat 或 ss 查看网络连接
# 查看 Nginx 网络连接
netstat -tuln | grep nginx
ss -tuln | grep nginx
# 查看所有连接状态
netstat -ant | grep ESTABLISHED | grep nginx
ss -ant | grep ESTAB | grep nginx
# 查看连接统计
netstat -s | grep -E "connections|accepts|refused"
ss -s
使用 htop 监控系统资源
# 安装 htop
sudo apt install htop # Ubuntu/Debian
sudo yum install htop # CentOS/RHEL
# 运行 htop
htop
# 按 P 按 CPU 使用率排序
# 按 M 按内存使用率排序
# 按 T 按运行时间排序
使用 perf 分析性能
# 安装 perf
sudo apt install linux-tools-common # Ubuntu/Debian
sudo yum install perf # CentOS/RHEL
# 分析 Nginx 进程性能
sudo perf record -p [Nginx PID]
# 查看性能报告
sudo perf report
# 快速分析
sudo perf top -p [Nginx PID]
实践练习
练习1:基本故障排查
- 故意修改 Nginx 配置文件,引入语法错误
- 使用
nginx -t检查配置错误 - 修复配置错误
- 重新加载配置并验证服务正常运行
练习2:处理 403 Forbidden 错误
- 创建一个测试文件:
echo "Test" > /var/www/html/test.txt - 设置错误的文件权限:
chmod 600 /var/www/html/test.txt - 尝试访问该文件,应该会收到 403 错误
- 查看 Nginx 错误日志,确认错误原因
- 修复文件权限:
chmod 644 /var/www/html/test.txt - 再次访问该文件,应该可以正常访问
练习3:处理 502 Bad Gateway 错误
- 配置 Nginx 反向代理到一个不存在的后端服务:
location /api { proxy_pass http://localhost:9999; } - 重新加载 Nginx 配置
- 尝试访问 /api 路径,应该会收到 502 错误
- 查看 Nginx 错误日志,确认错误原因
- 修复配置,指向正确的后端服务
- 再次访问,应该可以正常访问
常见问题解答
Q: Nginx 服务无法启动怎么办?
A: 按照以下步骤排查:
- 检查服务状态:
sudo systemctl status nginx - 查看错误日志:
tail -n 50 /var/log/nginx/error.log - 测试配置语法:
nginx -t - 检查端口是否被占用:
netstat -tuln | grep :80 - 尝试手动启动并查看详细错误:
nginx -g 'daemon off;'
Q: 如何查看 Nginx 版本信息?
A: 使用以下命令:
nginx -v # 查看版本号
nginx -V # 查看版本号和编译参数
Q: 如何查看 Nginx 正在使用的配置文件?
A: 使用以下命令:
nginx -t # 会显示配置文件路径
ps aux | grep nginx # 查看启动命令中的配置文件路径
Q: 如何备份和恢复 Nginx 配置?
A: 备份配置:
sudo tar -czf nginx-config-backup-$(date +%Y%m%d).tar.gz /etc/nginx/
恢复配置:
sudo tar -xzf nginx-config-backup-20240101.tar.gz -C /