Nginx配置全解析:从入门到精通
一、Nginx配置块层级结构(从外到内,作用域逐层缩小)
Nginx配置是树状嵌套结构,外层块的指令可被内层继承或覆盖。优先级原则:越内层越优先,但部分指令(如listen
、server_name
)只在特定块生效。
1. main 块(全局块)
- 作用:影响整个Nginx主进程和所有worker进程。
- 关键配置:
user www; worker_processes auto; # 自动匹配 CPU 核心数 worker_cpu_affinity auto; # 绑定 CPU,减少上下文切换(可选)(单机auto。有其他建议只绑定物理核心,超线程核心不绑定,或者绑定前一半核心,避免影响其他应用cpu使用,最好不绑定0 和1核 给系统用) #worker_rlimit_nofile 65536; # 每个 worker 最大文件描述符 #这个数字 包括Nginx的所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是是实际的井发连接数不能超过系统级别的最大打开文件数的限制(可以在systemd 启动文件里面配置) error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;
- 教训:没设
worker_rlimit_nofile
,LVS压测到3万连接时worker直接崩溃,全站502。
2. events 块
- 作用:控制worker如何处理网络事件。
- 调优配置
events {use epoll; # Linux 高性能 I/O 多路复用multi_accept on; # 一次尽可能接收多个连接worker_connections 65536; # 每个 worker 最大连接数accept_mutex on;#优化同一时刻只有一个请求而避免多个睡眠进程被唤醒的设置,on为防止被同时唤醒默认为off,全部唤醒的过程也成为“惊群”,因此nginx刚安装完以后要进行适当的优化。 }
- 原理:
worker_connections × worker_processes
= Nginx最大并发连接数。单机轻松扛10万+连接。
注意:
accept_mutex
在Nginx 1.11.3后默认off
,老版本务必显式关闭。
3. http 块(HTTP服务总控)
- 作用:定义所有HTTP行为的默认策略,是
server
和location
的父上下文。 - 生产配置模板:
http {include /etc/nginx/mime.types;default_type application/octet-stream;# 日志格式(结构化便于日志分析)log_format main_json escape=json '{''"time_local":"$time_local",''"remote_addr":"$remote_addr",''"request_id":"$request_id",''"request":"$request",''"status":$status,''"body_bytes_sent":$body_bytes_sent,''"http_referer":"$http_referer",''"http_user_agent":"$http_user_agent",''"upstream_addr":"$upstream_addr",''"upstream_response_time":"$upstream_response_time",''"request_time":$request_time''}';access_log /var/log/nginx/access.log main_json;# 性能优化charset utf-8;sendfile on; # 零拷贝传输tcp_nopush on; # 在开启了sendfile的情况下,合并请求后同意发送给客户端。tcp_nodelay off; # 实时发送小包(对 API 重要)在开启了keepalive模式下的链接是否启用TCP_NODELAY选项,当为off时延迟0.2s发送,默认on是,不延迟发送,立即发送用户相应报文。在server/location层按需开keepalive_timeout 65s; # 设置回话保持时间keepalive_requests 10000; # 单连接最大请求数types_hash_max_size 2048;# 客户端请求限制client_max_body_size 10m; # 上传文件最大 10MBclient_body_buffer_size 128k;# 超时设置client_header_timeout 10s;client_body_timeout 10s;send_timeout 10s;# Gzip 压缩(节省带宽)gzip on;gzip_vary on;gzip_min_length 1024;gzip_proxied any;gzip_comp_level 6;#省cpu可以降到3差别不大gzip_typestext/plaintext/cssapplication/jsonapplication/javascripttext/xmlapplication/xmlapplication/xml+rsstext/javascript;# 安全加固server_tokens off; # 隐藏 Nginx 版本号underscores_in_headers off; # 禁用下划线 header(防 header 污染)ignore_invalid_headers on;# 限制请求方法(可选)# if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 405; }# 防止 DDOS / CC 攻击(基于 IP 限流)limit_req_zone $binary_remote_addr zone=api:10m rate=50r/s; # API限流limit_req_zone $binary_remote_addr zone=static:10m rate=200r/s; # 静态资源限流limit_conn_zone $binary_remote_addr zone=perip_conn:10m;limit_conn perip_conn 100; # 新增:单IP最大并发连接数# 引入安全头配置include /etc/nginx/snippets/security.conf;# 核心:加载所有站点配置include /etc/nginx/conf.d/*.conf;# 默认兜底 server(拒绝未定义 Host 的请求)server {listen 80 default_server;server_name _;return 444;}
- 教训:没开
upstream keepalive
,后端Tomcat线程池被打满,RT飙升到5秒。
自动化建议:用SREWorks平台动态生成
upstream
(对接Nacos服务发现)。
4. server 块(虚拟主机)
- 作用:基于
server_name
或IP:Port路由请求到不同服务。 - 典型配置:
server {listen 80 reuseport;server_name www.zjx521.com m.zjx521.com;# 多域名明确声明root $INSTALL_PREFIX/html;index index.html index.htm;location / {try_files \$uri \$uri/ =404;}access_log /var/log/nginx/default.access.log main;error_log /var/log/nginx/default.error.log warn; }
- 匹配优先级:
listen
精确IP:Port > 通配IP:Port > 默认serverserver_name
精确匹配 > *前缀通配 > *后缀通配 > 正则 > default_server
教训:漏配
default_server
,DNS解析异常时流量打到错误服务,资损百万。
5. location 块(URI路由)
-
作用:按URI路径分发请求,支持静态文件、代理、重写等。
-
匹配优先级:
=
精确匹配(最高)^~
前缀匹配(匹配后跳过正则)~
/~*
正则匹配(区分/不区分大小写)- 普通前缀匹配(最长前缀胜出)
/
通用匹配(兜底)
-
实战配置:
# 1. 精确匹配:健康检查(最高优先级)
location = /status {stub_status on;allow 10.0.0.0/8;deny all;
}# 2. 前缀匹配:静态资源(不走正则,性能最优)
location ^~ /static/ {expires 1y;add_header Cache-Control "public, immutable";root /opt/nginx-1.26.3/html;
}# 3. 正则匹配:动态内容
location ~ \.php$ {fastcgi_pass unix:/var/run/php-fpm.sock;fastcgi_index index.php;include fastcgi_params;
}# 4. 普通前缀:API路由
location /api/v1/ {proxy_pass http://backend;
}# 5. 兜底:SPA应用
location / {try_files $uri $uri/ /index.html;
}
-
关键技巧:用
^~
避免正则开销(省10% CPU)。
安全响应头
info "创建安全响应头配置..."
cat > "/etc/nginx/snippets/security.conf" <<'EOF'
# 安全响应头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Content-Security-Policy "default-src 'self'; \
# script-src 'self' 'unsafe-inline' https://api.xxx.com https://x.zjx521.com; \
# img-src 'self' data: https://img.alicdn.com; \
# connect-src 'self' https://api.zjx521.com;" always;
#'unsafe-inline' 必须加!否则Vue/React框架报错
#按业务细化白名单(支付/图片/API分开)
#生产建议沟选
EOF
systemd文件
info "创建 systemd 服务文件..."
cat <<EOF | sudo tee "$SYSTEMD_SERVICE_FILE" > /dev/null
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=$INSTALL_PREFIX/sbin/nginx -c /etc/nginx/nginx.conf -t
ExecStart=$INSTALL_PREFIX/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=$INSTALL_PREFIX/sbin/nginx -c /etc/nginx/nginx.conf -s reload
ExecStop=/bin/kill -s QUIT \$MAINPID
PrivateTmp=true
LimitNOFILE=655350 # 修正上限
LimitNPROC=655350 # 防fork炸弹
# LimitNOFILE=655350 LimitNPROC=655350 设置worker最大并发数
[Install]
WantedBy=multi-user.target
EOF
配置日志轮转
配置 logrotate
info "配置日志轮转..."
cat <<EOF | sudo tee /etc/logrotate.d/nginx > /dev/null
/var/log/nginx/*.log {daily #服务器访问大那就 换为 hourly 按小时轮转size 1G #日志超过1G就切分missingokrotate 52 #保留时间 按小时就 168 (保留7天)compressdelaycompressnotifemptycreate 640 $NGINX_USER $NGINX_GROUPsharedscriptspostrotatetimeout 5 systemctl reload nginx || \(systemctl stop nginx && systemctl start nginx)endscript
}
EOF
站点配置示例(/etc/nginx/conf.d/myapp.conf)
upstream backend {# 健康检查 + 负载均衡server 10.0.1.10:8080 max_fails=2 fail_timeout=10s;server 10.0.1.11:8080 max_fails=2 fail_timeout=10s;server 10.0.1.12:8080 max_fails=2 fail_timeout=10s;# 负载均衡策略(默认 round-robin,也可用 least_conn、ip_hash)# keepalive 32; # 启用 upstream 长连接(需后端支持)
}server {listen 80 reuseport;server_name example.com;# 请求限流(防刷)limit_req zone=perip burst=20 nodelay;limit_conn perip_conn 20;# 设置请求 ID(用于全链路追踪)add_header X-Request-ID $request_id always;location / {proxy_pass http://backend;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;# 超时设置(必须小于 client timeout)proxy_connect_timeout 5s;proxy_send_timeout 10s;proxy_read_timeout 10s;# 缓冲优化(防后端慢拖垮 Nginx)proxy_buffering on;proxy_buffer_size 16k;proxy_buffers 8 32k;proxy_busy_buffers_size 64k;# 禁用不必要的 headerproxy_hide_header X-Powered-By;}# 静态资源缓存(CDN 回源场景常用)location ~* \.(js|css|png|jpg|jpeg|gif|ico|woff|woff2)$ {expires 1y;add_header Cache-Control "public, immutable";access_log off;}# 健康检查接口(供 LB 探活)location = /healthz {access_log off;return 200 "OK\n";}
}
二、配置继承与覆盖规则
指令类型 | 是否可继承 | 是否可覆盖 | 示例 |
---|---|---|---|
全局指令 | 否 | 否 | worker_processes |
HTTP上下文指令 | 是 | 是 | keepalive_timeout |
Server指令 | 否 | — | server_name |
Location指令 | 否 | — | proxy_pass |
黄金法则:
- 能在
http
块统一设的,绝不重复写在server
里(减少配置漂移)location
里只写差异化逻辑(如特定路径的限流、重写)
nginx -T #导出全量配置
安装配置脚本参考:https://blog.csdn.net/m0_66705547/article/details/152005024?sharetype=blogdetail&sharerId=152005024&sharerefer=PC&sharesource=m0_66705547&spm=1011.2480.3001.8118