Nginx 是什么
Nginx 是一款高性能的 HTTP 服务器、反向代理和负载均衡器。它采用事件驱动架构,单机可处理数万并发连接,资源占用远低于传统进程模型服务器。截至 2026 年,Nginx 在全球 Web 服务器市场占有率超过 35%,是互联网基础设施的核心组件。
版本选择
Nginx 有两个发布线:
| 发布线 | 当前版本 | 特点 |
|---|---|---|
| Stable(稳定版) | 1.28.2 | 仅安全修复,功能冻结,适合保守环境 |
| Mainline(主线版) | 1.29.5 | 新特性 + 安全修复,官方推荐生产使用 |
推荐主线版 1.29.5。理由:
- 稳定版和主线版的安全性相同(安全补丁同步回溯)
- 1.29.x 带来了 HTTP/3、HTTP/2 上游代理、add_header_inherit 等重要新特性
- 始终推荐使用最新版本以获取最新安全修复(例如 1.29.5 修复了多个 SSL 上游相关漏洞)
安装方式对比
| 方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 包管理器 | 大多数生产环境 | 自动更新、依赖管理、systemd 集成 | 需要添加官方仓库才能获得最新版 |
| Docker | 微服务、多实例、快速迁移 | 隔离性强、版本固定、可复现 | 需额外 Docker 知识、网络模式有损耗 |
| 源码编译 | 需要第三方模块或定制编译参数 | 完全可控、可选最新特性 | 维护成本高、需手动处理升级和安全补丁 |
方法一:官方仓库包管理器安装(推荐)
1. 添加 Nginx 官方仓库
系统自带仓库的 Nginx 版本通常较旧。推荐添加 Nginx 官方仓库获取最新稳定版。
Ubuntu / Debian:
# 安装依赖sudo apt update && sudo apt install -y curl gnupg2 ca-certificates lsb-release
# 添加官方 GPG 密钥curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
# 验证指纹(应为 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62)gpg --dry-run --quiet --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg | grep -A1 pub
# 添加仓库echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.listDebian 用户将 ubuntu 替换为 debian。
RHEL / AlmaLinux / Rocky Linux:
# 添加官方仓库sudo tee /etc/yum.repos.d/nginx.repo << 'EOF'[nginx-stable]name=nginx stable repobaseurl=http://nginx.org/packages/rhel/$releasever/$basearch/gpgcheck=1enabled=1gpgkey=https://nginx.org/keys/nginx_signing.keymodule_hotfixes=trueEOF2. 安装、启动、验证
# Ubuntu / Debiansudo apt update && sudo apt install -y nginx
# RHEL / AlmaLinux / Rocky Linuxsudo dnf install -y nginx
# 启动并设置开机自启sudo systemctl start nginxsudo systemctl enable nginx
# 验证nginx -v # 查看版本sudo systemctl status nginx # 检查运行状态curl -I http://localhost # 验证 HTTP 响应看到 HTTP/1.1 200 OK 即安装成功。
注意:官方仓库安装的 Nginx 默认以
nginx用户运行,配置文件位于/etc/nginx/nginx.conf,站点配置在/etc/nginx/conf.d/。
方法二:Docker 部署
1. 基础运行
# 拉取指定版本(生产环境禁止用 :latest)docker pull nginx:1.29.5
# 运行docker run -d \ --name nginx \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ nginx:1.29.52. 生产级部署(卷挂载 + 资源限制)
# 先创建目录结构mkdir -p ~/nginx/{conf,html,logs,ssl}
# 从容器中复制默认配置作为起点docker run --rm nginx:1.29.5 cat /etc/nginx/nginx.conf > ~/nginx/conf/nginx.conf
# 正式运行docker run -d \ --name nginx \ -p 80:80 \ -p 443:443 \ -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \ -v ~/nginx/conf/conf.d:/etc/nginx/conf.d:ro \ -v ~/nginx/html:/usr/share/nginx/html:ro \ -v ~/nginx/logs:/var/log/nginx \ -v ~/nginx/ssl:/etc/nginx/ssl:ro \ --memory 512m \ --cpus 2 \ --restart unless-stopped \ nginx:1.29.53. 重载配置(不重启容器)
# 检查配置docker exec nginx nginx -t
# 热重载docker exec nginx nginx -s reload方法三:源码编译安装
需要以下场景时选择源码编译:HTTP/3 + QUIC 支持、Brotli 压缩模块、自定义编译优化、最新主线特性。
1. 安装编译依赖
# Ubuntu / Debiansudo apt install -y build-essential libpcre2-dev zlib1g-dev libssl-dev \ perl libperl-dev libgd-dev libgeoip-dev libxml2-dev libxslt1-dev
# RHEL / AlmaLinux / Rocky Linuxsudo dnf groupinstall -y "Development Tools"sudo dnf install -y pcre2-devel zlib-devel openssl-devel perl-devel \ perl-ExtUtils-Embed gd-devel geoip-devel libxml2-devel libxslt-devel2. 下载源码与第三方模块
# 下载 Nginx 源码(以 1.29.5 为例)curl -fsSL https://nginx.org/download/nginx-1.29.5.tar.gz | tar xz
# Google Brotli 压缩模块(比 gzip 小 20-30%,CPU 开销略高)git clone --recurse-submodules https://github.com/google/ngx_brotli
# (可选)PCRE2 源码 —— 若系统 pcre2-dev 版本过旧# curl -fsSL https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.45/pcre2-10.45.tar.gz | tar xz3. 获取 OpenSSL 3.5+(HTTP/3 的硬依赖)
HTTP/3 需要 OpenSSL 3.5+ 的 QUIC API。
curl -fsSL https://github.com/openssl/openssl/releases/download/openssl-3.5.1/openssl-3.5.1.tar.gz | tar xz4. configure 参数详解
进入 Nginx 源码目录,执行 ./configure。以下是生产级配置范例,按功能分类:
cd nginx-1.29.5
./configure \ # ===== 路径配置 ===== --prefix=/usr/local/nginx \ --conf-path=/etc/nginx/nginx.conf \ --pid-path=/var/run/nginx.pid \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --lock-path=/var/run/nginx.lock \ \ # ===== HTTP 核心模块 ===== --with-http_ssl_module \ --with-http_v2_module \ --with-http_v3_module \ --with-http_realip_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-http_sub_module \ --with-http_addition_module \ --with-http_auth_request_module \ \ # ===== 性能相关 ===== --with-file-aio \ --with-threads \ --with-pcre-jit \ --with-http_slice_module \ \ # ===== 动态模块(不编入核心,运行时按需加载) ===== --add-dynamic-module=../ngx_brotli \ \ # ===== 编译器优化 ===== --with-cc-opt="-O2 -g -fstack-protector-strong -march=native -flto" \ --with-ld-opt="-Wl,-rpath,/usr/local/lib" \ \ # ===== OpenSSL 集成 ===== --with-openssl=../openssl-3.5.1 \ --with-openssl-opt="enable-tls1_3 no-weak-ssl-ciphers"关键参数说明:
| 参数 | 作用 |
|---|---|
--with-http_ssl_module | HTTPS 支持,HTTP/2、HTTP/3 的前置依赖 |
--with-http_v2_module | HTTP/2 支持(≥1.25.x 默认启用) |
--with-http_v3_module | HTTP/3 + QUIC 支持(需 OpenSSL 3.5+) |
--with-http_realip_module | 反向代理时获取客户端真实 IP |
--with-http_stub_status_module | 提供基础状态指标,供 Prometheus 采集 |
--with-http_gzip_static_module | 优先发送预压缩的 .gz 文件,省 CPU |
--with-file-aio | 异步 I/O,大文件传输加速 |
--with-threads | 线程池支持,减少磁盘 I/O 阻塞 |
--with-pcre-jit | PCRE JIT 编译,正则匹配加速 2-5 倍 |
--add-dynamic-module | 编译为动态模块(.so),运行时 load_module 加载 |
--with-cc-opt="-march=native" | GCC 针对当前 CPU 指令集优化(不跨机器部署时使用) |
--with-openssl-opt="no-weak-ssl-ciphers" | 编译器级别禁用弱加密套件 |
--with-cc-opt="-march=native"生成的二进制仅适用于当前 CPU。如果需要把编译好的 Nginx 分发到其他服务器,去掉此选项或改为-march=x86-64。
5. 编译与安装
# 编译(利用所有 CPU 核心)make -j$(nproc)
# 安装到 --prefix 指定的路径sudo make install
# 验证/usr/local/nginx/sbin/nginx -Vnginx -V 会打印所有编译参数和模块列表,这是排查模块缺失时的第一手信息来源。
6. 编写 systemd 服务文件
源码编译不自动生成 systemd 服务,需手动创建:
sudo tee /etc/systemd/system/nginx.service << 'EOF'[Unit]Description=The NGINX HTTP and reverse proxy serverAfter=network.target
[Service]Type=forkingPIDFile=/var/run/nginx.pidExecStartPre=/usr/local/nginx/sbin/nginx -tExecStart=/usr/local/nginx/sbin/nginxExecReload=/bin/kill -s HUP $MAINPIDExecStop=/bin/kill -s QUIT $MAINPIDKillSignal=SIGQUITTimeoutStopSec=5KillMode=processRestart=on-failureRestartSec=5
[Install]WantedBy=multi-user.targetEOF
# 启用并启动sudo systemctl daemon-reloadsudo systemctl enable nginxsudo systemctl start nginx7. 零停机平滑升级
源码编译的 Nginx 升级时,利用 master-worker 架构实现零停机:
# 备份当前二进制sudo cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
# 用新的 configure 参数编译(与旧版保持一致的路径配置,追加新模块即可)cd nginx-1.29.6 # 假设新版本./configure <与旧版相同的参数,可追加新模块>make -j$(nproc) # 注意:不要执行 make install
# 替换二进制文件sudo cp objs/nginx /usr/local/nginx/sbin/nginx
# 验证新二进制可用/usr/local/nginx/sbin/nginx -t
# 发送 USR2 信号:启动新 master(与旧 master 并存)sudo kill -USR2 $(cat /var/run/nginx.pid)
# 此时新旧两套 master + worker 同时运行,旧 worker 仍在处理已有连接# 优雅关闭旧 workersudo kill -WINCH $(cat /var/run/nginx.pid.oldbin)
# 确认旧 worker 全部退出后,终止旧 mastersudo kill -QUIT $(cat /var/run/nginx.pid.oldbin)
# 回滚方案(如果新版本有问题)# sudo kill -HUP $(cat /var/run/nginx.pid.oldbin) # 重新拉起旧 worker# sudo kill -QUIT $(cat /var/run/nginx.pid) # 关闭新 master# sudo cp /usr/local/nginx/sbin/nginx.old /usr/local/nginx/sbin/nginx # 还原二进制整个过程中
LISTEN套接字不会关闭,所有连接被正常处理。这是 Nginx 在生产环境升级的标准做法。
核心配置生产调优
默认的 nginx.conf 偏保守,生产环境需要调整以下参数。
1. 工作进程与连接
user nginx nginx;worker_processes auto; # 自动匹配 CPU 核数worker_rlimit_nofile 65535; # 提高文件描述符上限
events { worker_connections 4096; # 每 worker 最大连接数(默认 512 太低) multi_accept on; # 一次接受所有新连接 use epoll; # Linux 下最有效的事件模型}最大并发连接数 = worker_processes × worker_connections。4 核机器上 4 × 4096 = 16384 并发。
2. 文件传输与连接保持
http { sendfile on; # 零拷贝发送静态文件 tcp_nopush on; # 与 sendfile 配合,减少网络包数量 tcp_nodelay on; # keepalive 连接上立即发送小包 keepalive_timeout 65; # 长连接保持时间 keepalive_requests 100; # 单连接最大请求数}3. 缓冲区与超时
http { client_body_buffer_size 16k; client_header_buffer_size 1k; large_client_header_buffers 4 8k; # 大请求头缓冲(URL 过长时用到) client_max_body_size 10m; # 上传文件大小限制 client_body_timeout 12s; client_header_timeout 12s; send_timeout 10s; reset_timedout_connection on; # 超时连接立刻释放,不占用 FIN_WAIT}4. Gzip 压缩
压缩级别 5 是 CPU 开销和压缩率的平衡点。
http { gzip on; gzip_comp_level 5; gzip_min_length 256; # 小于 256 字节不压缩 gzip_vary on; # 响应头加 Vary: Accept-Encoding gzip_proxied any; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss image/svg+xml; gzip_disable "msie6"; # IE6 不压缩(有兼容问题)}如果编译了 Brotli 模块:
# 在主配置顶部加载动态模块load_module modules/ngx_http_brotli_filter_module.so;
http { brotli on; brotli_comp_level 6; # 推荐 4-6,11 CPU 翻倍但收益递减 brotli_min_length 256; brotli_types text/plain text/css application/json application/javascript text/xml image/svg+xml; brotli_static on; # 优先使用预压缩的 .br 文件
# Brotli 和 gzip 二选一,避免重复压缩(浏览器不支持 Brotli 时回退 gzip) gzip on; # 保留 gzip 作为回退}5. 静态资源缓存
server { location ~* \.(jpg|jpeg|png|gif|ico|webp|svg|css|js|woff|woff2|ttf|eot)$ { expires 30d; add_header Cache-Control "public, immutable"; }}immutable 告诉浏览器资源不会变,不用发 If-Modified-Since 请求验证。
Nginx 1.29.x 重点新特性配置
1.29.x 主线版引入了多项值得关注的新特性。以下列出已在主线中稳定可用的配置(实验性特性已标注)。
1. HTTP/3 + QUIC ✅ 生产就绪
HTTP/3 基于 UDP 的 QUIC 协议,消除了 TCP 队头阻塞。需要开放 UDP 443 端口。
# nginx.conf 全局配置中http { quic_retry on; # 防 QUIC 泛洪攻击 # quic_gso on; # 需要 Linux 内核 ≥5.4 且支持 UDP_SEGMENT
server { # 同时监听 QUIC (UDP) 和标准 HTTPS (TCP) listen 443 quic reuseport; listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# 告知客户端支持 HTTP/3 add_header Alt-Svc 'h3=":443"; ma=86400'; }}防火墙放行 UDP 443:
sudo ufw allow 443/udp2. HTTP/2 上游代理(1.29.4+)✅ 生产就绪(有限制)
此前 Nginx 代理到后端只能降级为 HTTP/1.1。1.29.4 起支持端到端 HTTP/2:
server { listen 443 ssl; server_name app.example.com;
location / { proxy_pass https://backend.example.com; proxy_http_version 2; # 与后端建立 HTTP/2 连接 # HPACK 头部压缩自动生效,减少延迟 }}当前限制:上游 HTTP/2 暂不支持请求多路复用(一个连接只处理一个请求)。此限制在 1.29.5 中仍存在,使用时需评估对并发性能的影响。
3. Encrypted Client Hello (ECH) 🧪 实验性,生产环境严禁使用
ECH 加密 TLS 握手中的 SNI 字段,防止中间件窥探用户访问的域名。
ECH 目前仍处于实验阶段,尚未进入 Nginx 主线。Nginx 官方主线代码中暂不包含 ssl_ech_file 指令。如需测试 ECH,需使用 Nginx 的 ECH 实验性分支或第三方 patch,并配合支持 ECH 的 OpenSSL 分支版本。生产环境不推荐启用。
4. add_header_inherit(1.29.3+)✅ 生产就绪
解决 Nginx 历史痛点:嵌套 location 块中的 add_header 会覆盖父级设置的头,导致安全头意外丢失。
server { add_header_inherit merge; # 合并而非覆盖 add_header Strict-Transport-Security "max-age=31536000" always;
location /api/ { add_header Content-Security-Policy "default-src 'self'"; # 响应同时包含 HSTS 和 CSP,而不是只有 CSP }}5. TLS 证书压缩(1.29.1+)✅ 生产就绪
压缩 TLS 握手时的证书链,减少握手数据传输量。
server { listen 443 ssl; ssl_certificate_compression on; # 需 OpenSSL 3.2+ 或 BoringSSL ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem;}6. TLS 签名算法审计(1.29.3+)✅ 生产就绪
http { log_format detailed '$remote_addr - $ssl_sigalg - $ssl_client_sigalg ' '[$time_local] "$request" $status';
access_log /var/log/nginx/access.log detailed;}$ssl_sigalg 和 $ssl_client_sigalg 让安全团队可以直接从日志中审计实际协商的签名算法,无需抓包分析。
安全加固
上线前逐项确认以下配置。每条都有明确的安全目的。
1. 隐藏版本信息
http { server_tokens off; # 不暴露 Nginx 版本号,降低针对性攻击风险}隐藏前:Server: nginx/1.29.5。隐藏后:Server: nginx。
2. 安全 HTTP 响应头
server { add_header_inherit merge; # 1.29.3+,让下面所有头在嵌套 location 中也生效
# 强制 HTTPS,一年内浏览器自动转换 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# 禁止被嵌入 iframe,防点击劫持 add_header X-Frame-Options "DENY" always;
# 禁止 MIME 类型嗅探 add_header X-Content-Type-Options "nosniff" always;
# 内容安全策略(根据业务调整) add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" always;
# 禁用旧浏览器 Referrer 信息泄露 add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 权限策略(限制浏览器 API) add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;}3. SSL/TLS 强化
server { listen 443 ssl;
# 仅允许 TLS 1.2 和 1.3(SSLv3、TLS 1.0、TLS 1.1 已不安全) ssl_protocols TLSv1.2 TLSv1.3;
# 现代加密套件(优先 ECDHE 前向保密) ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; ssl_prefer_server_ciphers on;
# 会话缓存(减少重复握手计算开销) ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; # 关闭 session tickets,保证前向保密
ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# DH 参数(RSA 密钥交换时的前向保密,≥2048 位) ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# OCSP Stapling(减少客户端 OCSP 查询延迟) ssl_stapling on; ssl_stapling_verify on;}生成 DH 参数文件:
sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 20484. 请求频率限制(防 DDoS / 暴力破解)
http { # 定义限流区域:按客户端 IP,10MB 约能存 16 万个 IP limit_req_zone $binary_remote_addr zone=general:10m rate=30r/s; limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
server { # 全站限流 limit_req zone=general burst=50 nodelay;
# 登录接口严格限流:每分钟 5 次 location /login { limit_req zone=login burst=3 nodelay; proxy_pass http://backend; } }}| 参数 | 含义 |
|---|---|
rate=30r/s | 长期平均速率:每秒 30 请求 |
burst=50 | 允许突发 50 个请求排队 |
nodelay | 突发请求立即处理,不排队等待 |
5. 限制并发连接数
http { limit_conn_zone $binary_remote_addr zone=per_ip:10m;
server { limit_conn per_ip 20; # 单个 IP 最大 20 并发连接 limit_conn_status 429; # 超限返回 429 Too Many Requests }}6. 禁止访问敏感文件
server { # 禁止访问隐藏文件(.env、.git 等) location ~ /\. { deny all; access_log off; log_not_found off; }
# 禁止访问配置文件和后端代码 location ~* \.(conf|ini|log|sh|sql|bak|swp|save)$ { deny all; access_log off; log_not_found off; }}7. IP 白名单管理后台
server { location /admin { allow 192.168.1.0/24; # 内网网段 allow 10.0.0.0/8; # VPN 网段 deny all; # 拒绝所有其他 IP
proxy_pass http://backend; }}8. 禁止不安全的 HTTP 方法
server { # 只允许 GET、POST、HEAD,拒绝 PUT、DELETE、TRACE 等 if ($request_method !~ ^(GET|POST|HEAD)$) { return 405; }}HTTPS 部署(Let’s Encrypt + Certbot)
1. 安装 Certbot
Ubuntu 26.04 LTS 及更新版本推荐 snap 方式(包管理器版本可能滞后)。
# 安装 snapd(如未安装)sudo apt install -y snapd
# 安装 certbotsudo snap install --classic certbotsudo ln -sf /snap/bin/certbot /usr/bin/certbot使用 python3-certbot-nginx 插件自动完成 Nginx 配置。
sudo apt install -y python3-certbot-nginx2. 获取证书
# --nginx 参数会让 certbot 自动修改 Nginx 配置,添加 HTTPS 和重定向sudo certbot --nginx -d example.com -d www.example.com交互过程:输入邮箱(用于证书到期提醒)→ 同意服务条款 → 选择是否重定向 HTTP 到 HTTPS(建议选 2,自动重定向)。
3. 验证自动续期
# 模拟续期测试sudo certbot renew --dry-run
# 查看续期定时器sudo systemctl status certbot.timerCertbot 安装后自动创建 systemd timer,每天检查两次,证书到期前 30 天内自动续期。
反向代理最佳实践
1. 标准反向代理配置
server { listen 443 ssl http2; server_name app.example.com;
location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1;
# 传递客户端信息 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;
# WebSocket 支持 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
# 超时 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s;
# 缓冲 proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 16k; }}2. 上游负载均衡
http { upstream backend { # 加权轮询(默认算法,weight 越大分到的请求越多) server 127.0.0.1:3000 weight=3; server 127.0.0.1:3001 weight=1; # 备用节点(所有主节点不可用时才启用) server 192.168.1.100:3000 backup;
# keepalive 连接池(减少与后端的 TCP 握手开销) keepalive 32; keepalive_timeout 60s; }
server { location / { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Connection ""; } }}3. 基于 SNI 的 Stream 代理(TCP/UDP 层)
Nginx 可以在 TCP/UDP 层做代理,适用于 HTTPS 直通(不做 TLS 终结)场景。
stream { # 通过 SNI 区分不同后端 map $ssl_preread_server_name $upstream_name { app1.example.com backend_app1; app2.example.com backend_app2; default backend_default; }
upstream backend_app1 { server 10.0.0.1:443; } upstream backend_app2 { server 10.0.0.2:443; } upstream backend_default { server 10.0.0.3:443; }
server { listen 443; proxy_pass $upstream_name; ssl_preread on; }}这需要编译时添加 --with-stream_ssl_preread_module。
日志、轮转与监控
1. 结构化日志格式
http { log_format main '$remote_addr - $http_x_forwarded_for - [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time uct=$upstream_connect_time ' 'uht=$upstream_header_time urt=$upstream_response_time';
access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log warn;}rt(request time)是排查慢请求的关键指标。
2. 日志轮转
源码编译安装不自动生成 logrotate 配置,需手动创建:
sudo tee /etc/logrotate.d/nginx << 'EOF'/var/log/nginx/*.log { daily missingok rotate 30 compress delaycompress notifempty create 640 nginx adm sharedscripts postrotate [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid) endscript}EOF关键参数:
| 参数 | 作用 |
|---|---|
rotate 30 | 保留 30 天(等保要求 ≥180 天则改为 180) |
delaycompress | 延迟一天压缩,确保日志写入完毕 |
USR1 信号 | 通知 Nginx 重开日志文件,不丢任何请求 |
3. 开启状态监控(Stub Status)
server { listen 127.0.0.1:8080; # 仅本地监听,不对外暴露 server_name localhost;
location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; }}访问 curl http://127.0.0.1:8080/nginx_status 输出示例:
Active connections: 291server accepts handled requests 16630948 16630948 31070465Reading: 6 Writing: 179 Waiting: 106| 指标 | 含义 |
|---|---|
| Active connections | 当前活跃连接数 |
| accepts | 已接受的连接总数 |
| handled | 已处理的连接总数(accepts 与 handled 相同说明无连接被丢弃) |
| Reading / Writing / Waiting | 正在读请求头 / 写响应 / keepalive 等待的连接数 |
4. 对接 Prometheus
生产环境推荐用 nginx-prometheus-exporter 把 stub_status 转成 Prometheus 格式:
# 运行 exporterdocker run -d \ --name nginx-exporter \ -p 9113:9113 \ nginx/nginx-prometheus-exporter:latest \ -nginx.scrape-uri=http://127.0.0.1:8080/nginx_status然后 Prometheus 配置中添加 job:
scrape_configs: - job_name: 'nginx' static_configs: - targets: ['127.0.0.1:9113']常用命令速查
| 命令 | 用途 |
|---|---|
nginx -t | 语法检查(每次改配置后先跑) |
nginx -T | dump 完整合并后的配置(调试用) |
nginx -s reload | 热重载配置,不中断连接 |
nginx -s stop | 快速停止 |
nginx -s quit | 优雅停止(处理完已有连接) |
nginx -s reopen | 重新打开日志文件 |
sudo systemctl restart nginx | 硬重启(短暂中断,不推荐生产环境) |
sudo systemctl status nginx | 查看运行状态 |
tail -f /var/log/nginx/error.log | 实时错误日志 |
tail -f /var/log/nginx/access.log | 实时访问日志 |
tail -f /var/log/nginx/access.log | awk '{print $NF}' | sort | uniq -c | sort -rn | head | 按响应时间排序的前 10 请求 |
总结:上线检查清单
部署完成后逐项确认:
-
nginx -t语法检查通过 -
server_tokens off版本信息已隐藏 - 安全响应头完整(HSTS、X-Frame-Options、CSP、X-Content-Type-Options)
- SSL 仅启用 TLS 1.2+,弱加密套件已禁用
- 敏感文件和隐藏文件禁止外部访问
- 管理后台配置 IP 白名单(如有)
- 请求频率限制和并发连接限制已配置
- 防火墙已放行 80/443 TCP(若启用了 HTTP/3 还需 443 UDP)
- logrotate 已配置并验证
- HTTPS 证书自动续期定时器运行正常
- stub_status 已开启并限制内网访问
-
reload替代restart作为日常变更手段