1. 为什么需要系统学习Nginx配置
第一次接触Nginx是在2013年接手一个高并发Web项目时。当时项目使用的Apache服务器在3000QPS时CPU就飙到了90%,而切换到Nginx后性能直接提升了5倍。这个经历让我意识到,掌握Nginx配置是后端工程师的必修课。
Nginx之所以能成为全球最受欢迎的Web服务器(Netcraft 2023年数据显示市场份额达33%),关键在于其事件驱动的异步架构。与传统的多线程/多进程模型不同,Nginx用单个进程就能处理数万并发连接,这种设计在C10K问题日益突出的今天显得尤为重要。
2. Nginx核心配置架构解析
2.1 配置文件组织结构
典型的nginx.conf包含三个核心区块:
nginx复制main {
# 全局配置
worker_processes auto;
error_log /var/log/nginx/error.log;
}
events {
# 连接处理配置
worker_connections 1024;
use epoll;
}
http {
# HTTP服务配置
include /etc/nginx/mime.types;
server {
listen 80;
server_name example.com;
location / {
root /var/www/html;
}
}
}
关键经验:建议将不同站点的配置拆分为独立文件,通过include指令引入。例如创建conf.d/目录存放各站点配置,这样维护更清晰。
2.2 指令作用域详解
Nginx配置指令的作用域规则常让新手困惑。根据我的踩坑经验:
- main作用域:影响整个Nginx实例的全局设置,如worker_processes
- events作用域:仅影响连接处理模块
- http作用域:所有HTTP相关配置的容器
- server作用域:虚拟主机级别的配置
- location作用域:URI路径匹配后的特定配置
特别注意:某些指令在不同作用域的表现不同。比如access_log在http/server/location都可设置,但error_log只能在main/http/server作用域。
3. 高性能配置实战技巧
3.1 连接优化参数
在电商大促场景下,这些参数调优使我们的Nginx稳定支撑了2万QPS:
nginx复制events {
worker_connections 20480;
multi_accept on;
use epoll;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
}
参数选择依据:
- worker_connections = worker_processes × 单个worker最大连接数
- epoll在Linux 2.6+内核效率最高
- tcp_nopush需要配合sendfile使用
3.2 缓存加速配置
静态资源缓存是提升性能的利器:
nginx复制server {
location ~* \.(jpg|png|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
access_log off;
}
}
实测这个配置使我们的CSS/JS加载时间从800ms降到80ms。注意no-transform可以防止CDN修改文件内容。
4. 安全加固方案
4.1 基础安全防护
这些配置能防御90%的常见攻击:
nginx复制server {
# 禁用不安全的HTTP方法
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 405;
}
# 隐藏Nginx版本号
server_tokens off;
# 防止MIME类型混淆攻击
add_header X-Content-Type-Options "nosniff";
}
4.2 HTTPS最佳实践
使用Let's Encrypt证书时的推荐配置:
nginx复制server {
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
}
重要提示:TLS 1.0/1.1已被主流浏览器弃用,生产环境务必禁用。
5. 高级负载均衡配置
5.1 后端服务器集群配置
这是我们线上使用的微服务负载均衡方案:
nginx复制upstream backend {
zone backend 64k;
server 10.0.0.1:8080 weight=5;
server 10.0.0.2:8080;
server 10.0.0.3:8080 backup;
least_conn;
keepalive 32;
}
server {
location /api {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
参数说明:
- weight设置服务器权重
- backup标记备用服务器
- least_conn使用最少连接算法
- keepalive减少TCP握手开销
5.2 健康检查机制
Nginx Plus才支持主动健康检查,开源版可以通过第三方模块或被动检查实现:
nginx复制upstream backend {
server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;
}
server {
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
}
通过max_fails和fail_timeout实现被动健康检查,再结合stub_status模块监控状态。
6. 常见问题排查指南
6.1 性能问题排查
当QPS下降时,我通常按这个顺序检查:
- 查看错误日志:
tail -f /var/log/nginx/error.log - 检查当前连接数:
netstat -ant | grep :80 | wc -l - 监控worker进程CPU:
top -p $(pgrep -d',' nginx) - 测试后端响应时间:
curl -o /dev/null -s -w '%{time_total}' http://backend
6.2 配置语法检查
每次修改配置后务必执行:
bash复制nginx -t
这个命令会测试配置语法而不重启服务。曾经因为跳过这步导致生产环境502错误,教训深刻。
7. 调试与日志分析技巧
7.1 定制化日志格式
调试复杂问题时,自定义日志格式非常有用:
nginx复制http {
log_format debug '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time"';
server {
access_log /var/log/nginx/access.log debug;
}
}
通过分析request_time和upstream_connect_time,可以快速定位性能瓶颈是在Nginx还是后端服务。
7.2 流量复制与压测
使用mirror模块可以将生产流量复制到测试环境:
nginx复制location / {
mirror /mirror;
proxy_pass http://backend;
}
location = /mirror {
internal;
proxy_pass http://test_backend$request_uri;
}
这个配置将1%的流量镜像到测试环境,不会影响原始请求的响应。