找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

224

积分

0

好友

27

主题
发表于 昨天 01:57 | 查看: 30| 回复: 0

一、概述

1.1 背景介绍

Nginx作为高性能的Web服务器和反向代理,是互联网基础设施的核心。随着业务规模增长,其需要处理的并发连接数从几万跃升至数十万乃至百万级别。默认配置远不能满足高并发需求,必须从应用层、系统层到内核层进行全方位性能调优。本文将系统讲解如何将Nginx的并发处理能力从10万提升至100万,涵盖配置优化、Linux内核调优、网络协议栈优化及硬件规划等多个维度。

1.2 技术特点

  • • 事件驱动架构:基于epoll/kqueue的异步非阻塞I/O模型,单worker进程可处理数万并发。
  • • 低内存消耗:1万个非活跃HTTP Keep-Alive连接仅消耗约2.5MB内存。
  • • 高度模块化:支持动态加载模块,灵活扩展功能。
  • • 反向代理与负载均衡:内置多种算法,支持健康检查和会话保持。
  • • 高效缓存机制:支持多种代理缓存,大幅降低后端压力。

1.3 适用场景

  • • 高并发Web服务:电商大促、社交媒体等需承载10万+并发的场景。
  • • API网关:作为微服务架构的统一入口,处理大量API请求并进行流量控制。
  • • 静态资源CDN节点:图片、视频等静态文件的高速分发。
  • • 反向代理与负载均衡器:作为应用服务器集群的前端代理。

1.4 环境要求

组件 版本要求 说明
操作系统 CentOS 7+/Ubuntu 18.04+ 建议64位系统,内核版本3.10+
Nginx 1.18.0+ (推荐1.24+) 使用主线版本以获得最新性能优化
CPU 8核心+ 10万并发建议8核,100万建议16-32核
内存 16GB+ 10万并发约需8GB,100万建议32GB+
网络 万兆网卡 高并发下网卡带宽是关键瓶颈
磁盘 SSD/NVMe 日志写入和缓存读写需要高IOPS支持

二、详细步骤

2.1 准备工作

◆ 2.1.1 系统检查
# 检查系统版本和内核
cat /etc/os-release
uname -r
# 检查CPU核心数
lscpu | grep "CPU(s):"
nproc
# 检查内存状况
free -h
cat /proc/meminfo | grep MemTotal
# 检查磁盘IO性能
df -h
iostat -x 1 5
# 检查网络接口
ip addr show
ethtool eth0 | grep Speed
# 检查当前文件描述符限制
ulimit -n
cat /proc/sys/fs/file-max
# 检查当前连接数
ss -s
netstat -an | grep ESTABLISHED | wc -l
◆ 2.1.2 安装Nginx
# CentOS/RHEL系统
sudo yum install -y epel-release
sudo yum install -y nginx
# 或编译安装最新版本(推荐)
sudo yum install -y gcc gcc-c++ make zlib-devel pcre-devel openssl-devel
# 下载Nginx源码
cd /usr/local/src
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0
# 编译安装(启用关键模块)
./configure \
  --prefix=/usr/local/nginx \
  --with-http_stub_status_module \
  --with-http_ssl_module \
  --with-http_realip_module \
  --with-http_gzip_static_module \
  --with-http_v2_module \
  --with-file-aio \
  --with-threads
make -j$(nproc)
sudo make install
# Ubuntu/Debian系统
sudo apt update
sudo apt install -y nginx
# 验证安装
nginx -v
◆ 2.1.3 系统基础优化
# 备份原始配置
sudo cp /etc/sysctl.conf /etc/sysctl.conf.bak
sudo cp /etc/security/limits.conf /etc/security/limits.conf.bak
# 创建优化脚本
sudo tee /etc/security/limits.d/nginx.conf > /dev/null <<EOF
# Nginx进程文件描述符限制
nginx soft nofile 1048576
nginx hard nofile 1048576
nginx soft nproc 65535
nginx hard nproc 65535
# 所有用户限制(如果Nginx以root启动)
* soft nofile 1048576
* hard nofile 1048576
* soft nproc 65535
* hard nproc 65535
EOF
# 修改系统全局文件描述符限制
echo "fs.file-max = 2097152" | sudo tee -a /etc/sysctl.conf
# 应用配置
sudo sysctl -p
# 验证配置
ulimit -n
cat /proc/sys/fs/file-max

2.2 核心配置

◆ 2.2.1 Nginx主配置文件优化(10万并发级别)
# 文件路径:/etc/nginx/nginx.conf 或 /usr/local/nginx/conf/nginx.conf
# 运行用户
user nginx;
# Worker进程数:设置为CPU核心数
worker_processes auto;
# 绑定worker进程到特定CPU核心,避免CPU缓存失效
worker_cpu_affinity auto;
# 错误日志级别(生产环境建议warn)
error_log /var/log/nginx/error.log warn;
# PID文件
pid /var/run/nginx.pid;
# 单个worker进程最大文件描述符数量
worker_rlimit_nofile 65535;

# 事件模块配置
events {
# 使用epoll事件模型(Linux系统最高效)
use epoll;
# 单个worker进程最大并发连接数
# 10万并发:65535 / 8核 ≈ 8192每核
worker_connections 8192;
# 允许尽可能多地接受连接
multi_accept on;
# 互斥锁文件(off表示不使用,减少锁竞争)
accept_mutex off;
}

http {
# 基础设置
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/access.log main buffer=32k flush=5s;

# 高性能设置
sendfile on;              # 启用零拷贝技术
tcp_nopush on;            # 数据包累积到一定大小再发送
tcp_nodelay on;           # 小数据包立即发送(与tcp_nopush配合)

# Keepalive优化
keepalive_timeout 65;     # 客户端连接保持时间
keepalive_requests 1000;  # 单个连接最大请求数

# 上游服务器Keepalive
upstream backend {
server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.102:8080 max_fails=3 fail_timeout=30s;
# 保持与后端的长连接
keepalive 256;
keepalive_timeout 60s;
keepalive_requests 1000;
    }

# 哈希表优化
server_names_hash_bucket_size 128;
server_names_hash_max_size 512;
types_hash_max_size 2048;

# 客户端请求限制
client_header_buffer_size 4k;
large_client_header_buffers 4 32k;
client_max_body_size 100m;
client_body_buffer_size 256k;
client_header_timeout 15s;
client_body_timeout 15s;
send_timeout 60s;

# Gzip压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
               application/json application/javascript application/xml+rss
               application/rss+xml font/truetype font/opentype
               application/vnd.ms-fontobject image/svg+xml;
gzip_min_length 1000;
gzip_buffers 16 8k;
gzip_http_version 1.1;

# 禁用不必要的功能
server_tokens off;

# 打开文件缓存
open_file_cache max=10000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

# 虚拟主机配置
server {
listen 80 reuseport backlog=8192;
server_name example.com;
root /var/www/html;
index index.html index.htm;
# 访问日志(高并发场景可关闭)
access_log off;
# access_log /var/log/nginx/example.access.log main;

location / {
try_files $uri $uri/ =404;
        }

# 反向代理配置
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
# Keepalive设置
proxy_set_header Connection "";
# 代理头设置
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;
# 超时设置
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲设置
proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 32 8k;
proxy_busy_buffers_size 64k;
        }

# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
        }

# 状态监控页面
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
        }
    }
}

说明:此配置适用于10万并发场景,核心参数包括:

  • • worker_processes auto:自动设置为CPU核心数。
  • • worker_connections 8192:每个worker支持8192个并发连接。
  • • keepalive 256:与后端保持256个长连接。
  • • reuseport:启用端口复用,减少锁竞争。
◆ 2.2.2 Linux内核参数优化(支持100万并发)
# 创建内核优化配置文件
sudo tee /etc/sysctl.d/99-nginx-performance.conf > /dev/null <<'EOF'
# ========== 网络核心参数 ==========
# 最大文件句柄数
fs.file-max = 2097152
# 最大文件监控数(用于inotify)
fs.inotify.max_user_watches = 524288

# ========== TCP/IP协议栈优化 ==========
# TCP连接队列长度
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 262144
# TCP缓冲区设置(min default max,单位字节)
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.rmem_default = 262144
net.core.wmem_default = 262144
# TCP连接优化
net.ipv4.tcp_syncookies = 1               # 启用SYN Cookies防护
net.ipv4.tcp_tw_reuse = 1                 # 允许TIME_WAIT复用
net.ipv4.tcp_fin_timeout = 15             # FIN_WAIT_2超时时间
net.ipv4.tcp_keepalive_time = 600         # Keepalive探测间隔
net.ipv4.tcp_keepalive_probes = 3         # Keepalive探测次数
net.ipv4.tcp_keepalive_intvl = 15         # 探测包发送间隔
# TCP快速回收和时间戳
net.ipv4.tcp_max_tw_buckets = 2000000     # TIME_WAIT最大数量
net.ipv4.tcp_timestamps = 1               # 启用时间戳
net.ipv4.tcp_max_syn_backlog = 262144     # SYN队列长度
# TCP拥塞控制(使用BBR算法,需内核4.9+)
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# TCP快速打开(TFO)
net.ipv4.tcp_fastopen = 3                 # 1=客户端 2=服务端 3=双向
# IP本地端口范围
net.ipv4.ip_local_port_range = 1024 65535
# 最大跟踪连接数(conntrack)
net.netfilter.nf_conntrack_max = 2097152
net.nf_conntrack_max = 2097152
# 连接跟踪表超时时间
net.netfilter.nf_conntrack_tcp_timeout_established = 1200
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 15
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 30

# ========== 虚拟内存和交换分区 ==========
vm.swappiness = 10                        # 降低swap使用倾向
vm.dirty_ratio = 15                       # 脏页比例触发写入
vm.dirty_background_ratio = 5             # 后台写入触发比例
vm.overcommit_memory = 1                  # 允许内存过量分配

# ========== 安全设置 ==========
net.ipv4.conf.default.rp_filter = 1       # 反向路径过滤
net.ipv4.conf.all.rp_filter = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1  # 忽略ICMP广播
net.ipv4.icmp_ignore_bogus_error_responses = 1
EOF

# 应用配置
sudo sysctl -p /etc/sysctl.d/99-nginx-performance.conf
# 验证BBR是否启用
sysctl net.ipv4.tcp_congestion_control
lsmod | grep bbr
# 如果BBR未加载,手动加载(需内核4.9+)
echo "tcp_bbr" | sudo tee -a /etc/modules-load.d/modules.conf
sudo modprobe tcp_bbr

参数说明

  • • net.core.somaxconn:监听队列最大长度,影响accept性能。
  • • net.ipv4.tcp_max_syn_backlog:SYN队列长度,防止SYN Flood攻击。
  • • net.ipv4.tcp_tw_reuse:复用TIME_WAIT状态的连接,节省端口资源。
  • • net.ipv4.tcp_congestion_control = bbr:使用BBR拥塞控制算法,提升吞吐量。
  • • net.netfilter.nf_conntrack_max:连接跟踪表大小,100万并发必须调大。
◆ 2.2.3 100万并发级别配置
# 文件路径:/etc/nginx/nginx.conf
user nginx;
worker_processes 16;  # 假设为16核CPU
worker_cpu_affinity auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# 100万并发需要更大的文件描述符数
worker_rlimit_nofile 1048576;
# 启用线程池处理阻塞操作
thread_pool default threads=32 max_queue=65536;

events {
use epoll;
# 100万并发:1000000 / 16核 = 62500每核(向上取整到65535)
worker_connections 65535;
multi_accept on;
accept_mutex off;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志优化:关闭访问日志或异步写入
access_log off;
# 或使用缓冲异步写入
# access_log /var/log/nginx/access.log main buffer=128k flush=3s;
error_log /var/log/nginx/error.log crit;

# 零拷贝和线程池
sendfile on;
aio threads=default;  # 使用线程池处理AIO
directio 4m;          # 大于4MB的文件使用直接IO
tcp_nopush on;
tcp_nodelay on;

# Keepalive优化(更激进)
keepalive_timeout 30;
keepalive_requests 10000;
reset_timedout_connection on;  # 重置超时连接

# 上游Keepalive连接池(增大)
upstream backend {
server 192.168.1.101:8080 max_fails=2 fail_timeout=10s weight=1;
server 192.168.1.102:8080 max_fails=2 fail_timeout=10s weight=1;
server 192.168.1.103:8080 max_fails=2 fail_timeout=10s weight=1;
server 192.168.1.104:8080 max_fails=2 fail_timeout=10s weight=1;
# 更大的连接池
keepalive 1024;
keepalive_timeout 60s;
keepalive_requests 10000;
    }

# 哈希表优化
server_names_hash_bucket_size 256;
server_names_hash_max_size 1024;
types_hash_max_size 4096;

# 客户端限制
client_header_buffer_size 2k;
large_client_header_buffers 4 8k;
client_max_body_size 50m;
client_body_buffer_size 128k;
client_header_timeout 10s;
client_body_timeout 10s;
send_timeout 30s;

# Gzip配置(降低压缩级别减少CPU消耗)
gzip on;
gzip_vary on;
gzip_comp_level 4;  # 从6降到4
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
gzip_disable "msie6";

# 打开文件缓存(扩大)
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

# 请求限流(防止滥用)
limit_req_zone $binary_remote_addr zone=req_limit:100m rate=100r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:100m;

server {
listen 80 reuseport deferred backlog=65535;
server_name example.com;
root /data/www;
index index.html;
access_log off;
error_log /var/log/nginx/error.log crit;
# 应用限流规则
limit_req zone=req_limit burst=200 nodelay;
limit_conn conn_limit 50;

location / {
try_files $uri $uri/ =404;
        }

location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
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_connect_timeout 3s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# 优化缓冲
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 64 4k;
proxy_busy_buffers_size 32k;
# 失败重试
proxy_next_upstream error timeout http_500 http_502 http_503;
proxy_next_upstream_tries 2;
proxy_next_upstream_timeout 3s;
        }

# 静态文件
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
        }
    }
}

2.3 启动和验证

◆ 2.3.1 启动服务
# 检查配置文件语法
nginx -t
sudo /usr/local/nginx/sbin/nginx -t
# 启动Nginx
sudo systemctl start nginx
# 或
sudo /usr/local/nginx/sbin/nginx
# 设置开机自启
sudo systemctl enable nginx
# 查看服务状态
sudo systemctl status nginx
ps aux | grep nginx
# 查看worker进程数和CPU绑定
ps -eLo ruser,pid,ppid,lwp,psr,args | grep nginx | grep worker
# 重新加载配置(平滑重启)
sudo nginx -s reload
sudo systemctl reload nginx
◆ 2.3.2 功能验证
# 验证Nginx版本和编译模块
nginx -V
# 验证监听端口
ss -tlnp | grep nginx
netstat -tlnp | grep nginx
# 验证worker进程数
ps aux | grep nginx | grep worker | wc -l
# 访问状态页面
curl http://localhost/nginx_status
# 预期输出
Active connections: 2891
server accepts handled requests
 1234567 1234567 8901234
Reading: 10 Writing: 20 Keeping: 2861
# 简单压力测试
ab -n 10000 -c 1000 http://localhost/
wrk -t12 -c400 -d30s http://localhost/
# 查看连接状态分布
ss -tan | awk '{print $1}' | sort | uniq -c
netstat -n | awk '/^tcp/ {print $6}' | sort | uniq -c
# 查看当前打开的文件描述符
lsof -p $(pgrep nginx | head -1) | wc -l
cat /proc/$(pgrep nginx | head -1)/limits | grep "open files"

三、示例代码和配置

3.1 完整配置示例

◆ 3.1.1 高性能静态文件服务器配置
# 文件路径:/etc/nginx/conf.d/static.conf
upstream img_backend {
# 一致性哈希负载均衡(基于URL)
hash $request_uri consistent;
server 192.168.1.11:80 max_fails=2 fail_timeout=10s;
server 192.168.1.12:80 max_fails=2 fail_timeout=10s;
server 192.168.1.13:80 max_fails=2 fail_timeout=10s;
server 192.168.1.14:80 max_fails=2 fail_timeout=10s;
}

# Proxy缓存配置
proxy_cache_path /data/nginx/cache
                 levels=1:2
                 keys_zone=img_cache:500m
                 max_size=50g
                 inactive=30d
                 use_temp_path=off;

server {
listen 80 reuseport deferred;
server_name static.example.com;
root /data/static;
access_log off;

# 图片防盗链
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
    }

# 缓存配置
location ~* \.(jpg|jpeg|png|gif|webp)$ {
# 代理到后端存储
proxy_pass http://img_backend;
# 缓存设置
proxy_cache img_cache;
proxy_cache_key $uri;
proxy_cache_valid 200 304 30d;
proxy_cache_valid 404 10m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
# 添加缓存头
add_header X-Cache-Status $upstream_cache_status;
add_header Cache-Control "public, max-age=2592000";
# 过期时间
expires 30d;
# 跨域设置
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, OPTIONS";
    }

# CSS/JS缓存
location ~* \.(css|js)$ {
expires 7d;
add_header Cache-Control "public, immutable";
gzip_static on;  # 使用预压缩文件
    }

# 字体文件
location ~* \.(woff|woff2|ttf|otf|eot)$ {
expires 365d;
add_header Access-Control-Allow-Origin *;
    }
}
◆ 3.1.2 自动化性能调优脚本
#!/bin/bash
# Nginx性能自动调优脚本
# 文件名:nginx_performance_tuning.sh
set -e

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${GREEN}========== Nginx性能自动调优工具 ==========${NC}"

# 检测CPU核心数
CPU_CORES=$(nproc)
echo -e "${YELLOW}检测到CPU核心数: ${CPU_CORES}${NC}"
# 检测内存大小(GB)
TOTAL_MEM_GB=$(free -g | awk '/^Mem:/{print $2}')
echo -e "${YELLOW}系统总内存: ${TOTAL_MEM_GB}GB${NC}"

# 计算推荐的worker_connections
# 目标:支持10万并发
TARGET_CONNECTIONS=100000
WORKER_CONNECTIONS=$((TARGET_CONNECTIONS / CPU_CORES))
if [ $WORKER_CONNECTIONS -gt 65535 ]; then
    WORKER_CONNECTIONS=65535
fi
echo -e "${YELLOW}推荐worker_connections: ${WORKER_CONNECTIONS}${NC}"

# 计算文件描述符数量
FILE_MAX=$((TARGET_CONNECTIONS * 2))
if [ $FILE_MAX -lt 1048576 ]; then
    FILE_MAX=1048576
fi

# 备份原配置
BACKUP_DIR="/root/nginx_backup_$(date +%Y%m%d_%H%M%S)"
mkdir -p $BACKUP_DIR
cp /etc/nginx/nginx.conf $BACKUP_DIR/
cp /etc/sysctl.conf $BACKUP_DIR/
cp /etc/security/limits.conf $BACKUP_DIR/
echo -e "${GREEN}配置文件已备份到: ${BACKUP_DIR}${NC}"

# 优化系统参数
echo -e "${YELLOW}正在优化系统内核参数...${NC}"
cat > /etc/sysctl.d/99-nginx-tuning.conf <<EOF
fs.file-max = ${FILE_MAX}
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.ip_local_port_range = 1024 65535
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
vm.swappiness = 10
EOF
sysctl -p /etc/sysctl.d/99-nginx-tuning.conf

# 优化文件描述符限制
echo -e "${YELLOW}正在优化文件描述符限制...${NC}"
cat > /etc/security/limits.d/nginx.conf <<EOF
* soft nofile ${FILE_MAX}
* hard nofile ${FILE_MAX}
* soft nproc 65535
* hard nproc 65535
EOF

# 生成优化的Nginx配置
echo -e "${YELLOW}生成Nginx优化配置...${NC}"
cat > /tmp/nginx_optimized.conf <<EOF
user nginx;
worker_processes ${CPU_CORES};
worker_cpu_affinity auto;
worker_rlimit_nofile ${FILE_MAX};

events {
    use epoll;
    worker_connections ${WORKER_CONNECTIONS};
    multi_accept on;
    accept_mutex off;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    keepalive_requests 1000;
    access_log off;
    error_log /var/log/nginx/error.log warn;
    gzip on;
    gzip_comp_level 5;
    gzip_types text/plain text/css application/json application/javascript;
    include /etc/nginx/conf.d/*.conf;
}
EOF
echo -e "${GREEN}优化配置已生成: /tmp/nginx_optimized.conf${NC}"
echo -e "${YELLOW}请手动检查并替换: cp /tmp/nginx_optimized.conf /etc/nginx/nginx.conf${NC}"

# 检测BBR
echo -e "${YELLOW}检查TCP BBR状态...${NC}"
if sysctl net.ipv4.tcp_congestion_control | grep -q bbr; then
echo -e "${GREEN}BBR已启用${NC}"
else
echo -e "${RED}BBR未启用,正在尝试启用...${NC}"
    modprobe tcp_bbr 2>/dev/null || echo -e "${RED}BBR启用失败,需要内核4.9+${NC}"
echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.d/99-nginx-tuning.conf
    sysctl -p /etc/sysctl.d/99-nginx-tuning.conf
fi

# 性能报告
echo -e "\n${GREEN}========== 性能调优报告 ==========${NC}"
echo -e "CPU核心数: ${CPU_CORES}"
echo -e "Worker进程数: ${CPU_CORES}"
echo -e "每Worker连接数: ${WORKER_CONNECTIONS}"
echo -e "理论最大并发: $((CPU_CORES * WORKER_CONNECTIONS))"
echo -e "文件描述符限制: ${FILE_MAX}"
echo -e "系统内存: ${TOTAL_MEM_GB}GB"
echo -e "${YELLOW}请执行以下命令应用配置:${NC}"
echo -e "  1. cp /tmp/nginx_optimized.conf /etc/nginx/nginx.conf"
echo -e "  2. nginx -t"
echo -e "  3. systemctl reload nginx"
echo -e "  4. reboot (可选,确保所有内核参数生效)"

3.2 实际应用案例

◆ 案例一:电商大促高并发场景

场景描述:某电商平台大促活动期间,预计峰值并发50万,需要优化Nginx配置以应对流量洪峰。

实现步骤

  1. 硬件准备:32核CPU、64GB内存、万兆网卡
  2. 内核参数调优:调整TCP参数和连接跟踪表
  3. Nginx配置优化:增加worker进程和连接数

完整配置

# 50万并发配置
user nginx;
worker_processes 32;
worker_cpu_affinity auto;
worker_rlimit_nofile 1048576;

events {
use epoll;
worker_connections 20000;  # 32 * 20000 = 640000理论并发
multi_accept on;
accept_mutex off;
}

http {
# 日志完全关闭(大促期间)
access_log off;
error_log /dev/null crit;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 更短的超时时间
keepalive_timeout 30;
keepalive_requests 5000;
reset_timedout_connection on;

# 限流保护
limit_req_zone $binary_remote_addr zone=api_limit:200m rate=200r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:200m;

upstream app_backend {
        least_conn;  # 最少连接算法
server 10.0.1.11:8080 max_fails=2 fail_timeout=5s weight=5;
server 10.0.1.12:8080 max_fails=2 fail_timeout=5s weight=5;
server 10.0.1.13:8080 max_fails=2 fail_timeout=5s weight=3;
server 10.0.1.14:8080 max_fails=2 fail_timeout=5s weight=3;
keepalive 2000;
keepalive_timeout 60s;
keepalive_requests 5000;
    }

server {
listen 80 reuseport deferred backlog=65535;
server_name www.example.com;
limit_req zone=api_limit burst=500 nodelay;
limit_conn conn_limit 100;

location / {
proxy_pass http://app_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
# 快速失败
proxy_connect_timeout 2s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
proxy_next_upstream error timeout http_502 http_503;
proxy_next_upstream_tries 1;
        }
    }
}

运行结果

# 压测结果(使用wrk)
wrk -t32 -c50000 -d60s --latency http://www.example.com/
Running 60s test @ http://www.example.com/
  32 threads and 50000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    45.23ms   12.34ms 210.45ms   89.34%
    Req/Sec    35.67k     2.34k   42.12k    91.23%
  Latency Distribution
     50%   42.11ms
     75%   51.23ms
     90%   62.45ms
     99%   98.76ms
  68234567 requests in 60.00s, 12.34GB read
Requests/sec: 1137242.78
Transfer/sec:    210.45MB
# 实际承载:113万QPS,平均延迟45ms
◆ 案例二:CDN节点静态资源加速

场景描述:为视频网站部署CDN边缘节点,需要优化静态文件(图片、视频切片)的传输性能。

实现配置

# 文件路径:/etc/nginx/conf.d/cdn.conf
# 缓存路径配置
proxy_cache_path /data/cache/images
    levels=2:2
    keys_zone=img_cache:1g
    max_size=200g
    inactive=90d
    use_temp_path=off
    manager_files=1000
    manager_threshold=2000
    loader_files=500;

proxy_cache_path /data/cache/videos
    levels=1:2
    keys_zone=video_cache:2g
    max_size=500g
    inactive=30d
    use_temp_path=off;

# 源站配置
upstream origin_server {
server origin.example.com:80;
keepalive 100;
}

server {
listen 80 reuseport deferred;
server_name cdn.example.com;
root /data/static;
access_log off;

# 图片缓存
location ~* \.(jpg|jpeg|png|gif|webp|ico)$ {
# 优先本地文件
try_files $uri @origin;
expires 90d;
add_header Cache-Control "public, immutable";
add_header X-Cache-Status "HIT-LOCAL";
    }

# 回源获取
location @origin {
proxy_pass http://origin_server;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
# 缓存配置
proxy_cache img_cache;
proxy_cache_key $scheme://$host$uri;
proxy_cache_valid 200 304 90d;
proxy_cache_valid 404 10m;
# 缓存锁(避免缓存击穿)
proxy_cache_lock on;
proxy_cache_lock_timeout 10s;
proxy_cache_lock_age 5s;
# 过期更新
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
proxy_cache_background_update on;
# 分片缓存(大文件)
slice 1m;
proxy_cache_key $uri$is_args$args$slice_range;
proxy_set_header Range $slice_range;
proxy_cache_valid 200 206 90d;
add_header X-Cache-Status $upstream_cache_status;
add_header X-Slice-Range $slice_range;
expires 90d;
    }

# 视频切片(HLS)
location ~* \.(m3u8|ts)$ {
proxy_pass http://origin_server;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache video_cache;
proxy_cache_key $uri;
proxy_cache_valid 200 1h;
add_header Cache-Control "public, max-age=3600";
add_header X-Cache-Status $upstream_cache_status;
    }
}

效果

  • • 缓存命中率达到95%以上。
  • • 回源带宽降低90%。
  • • 用户访问延迟从200ms降至20ms。
◆ 案例三:API网关限流与负载均衡

场景描述:微服务架构中的API网关,需要实现限流、熔断、负载均衡功能,这是构建稳健后端架构的关键组件。

实现步骤

  1. 配置多级限流策略(IP级、API级)。
  2. 实现健康检查和自动摘除故障节点。
  3. 配置不同的负载均衡算法。

配置文件

# 文件路径:/etc/nginx/conf.d/api-gateway.conf
# 限流区域定义
limit_req_zone $binary_remote_addr zone=global_limit:50m rate=1000r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=api_limit:30m rate=100r/s;
# 连接限制
limit_conn_zone $binary_remote_addr zone=addr_conn:20m;
limit_conn_zone $server_name zone=server_conn:10m;

# 后端服务集群
upstream user_service {
# IP哈希保持会话
    ip_hash;
server 10.0.2.11:8080 max_fails=3 fail_timeout=30s;
server 10.0.2.12:8080 max_fails=3 fail_timeout=30s;
server 10.0.2.13:8080 max_fails=3 fail_timeout=30s backup;
keepalive 200;
}

upstream order_service {
# 加权轮询
server 10.0.3.11:8080 weight=5 max_fails=2 fail_timeout=10s;
server 10.0.3.12:8080 weight=3 max_fails=2 fail_timeout=10s;
server 10.0.3.13:8080 weight=2 max_fails=2 fail_timeout=10s;
keepalive 300;
}

upstream product_service {
# 最少连接
    least_conn;
server 10.0.4.11:8080;
server 10.0.4.12:8080;
keepalive 150;
}

# 日志格式(包含限流信息)
log_format api_log '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $request_time $upstream_response_time '
'limit_status=$limit_req_status';

server {
listen 443 ssl http2 reuseport;
server_name api.example.com;
ssl_certificate /etc/nginx/ssl/api.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/api.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
access_log /var/log/nginx/api.access.log api_log buffer=32k flush=5s;

# 全局限流
limit_req zone=global_limit burst=2000 nodelay;
limit_conn addr_conn 200;
limit_conn server_conn 10000;

# 健康检查端点(不限流)
location /health {
access_log off;
return 200 "OK\n";
    }

# 登录接口(严格限流)
location /api/v1/login {
limit_req zone=login_limit burst=20 nodelay;
proxy_pass http://user_service;
proxy_http_version 1.1;
proxy_set_header Connection "";
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_connect_timeout 3s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
    }

# 用户服务
location /api/v1/user/ {
limit_req zone=api_limit burst=200 nodelay;
proxy_pass http://user_service;
proxy_http_version 1.1;
proxy_set_header Connection "";
include proxy_headers.conf;
    }

# 订单服务
location /api/v1/order/ {
limit_req zone=api_limit burst=300;
proxy_pass http://order_service;
proxy_http_version 1.1;
proxy_set_header Connection "";
include proxy_headers.conf;
# 熔断:快速失败
proxy_next_upstream error timeout http_500 http_502 http_503;
proxy_next_upstream_tries 2;
proxy_next_upstream_timeout 5s;
    }

# 商品服务(支持缓存)
location /api/v1/product/ {
# 缓存GET请求
proxy_cache_methods GET HEAD;
proxy_cache product_cache;
proxy_cache_key $uri$is_args$args;
proxy_cache_valid 200 5m;
proxy_cache_use_stale updating;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://product_service;
proxy_http_version 1.1;
proxy_set_header Connection "";
include proxy_headers.conf;
    }
}

# 产品缓存配置
proxy_cache_path /data/cache/product
    levels=1:2
    keys_zone=product_cache:100m
    max_size=5g
    inactive=1h;

proxy_headers.conf共享配置

# 文件路径:/etc/nginx/proxy_headers.conf
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;
proxy_set_header X-Request-ID $request_id;
# 安全头
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";

四、最佳实践和注意事项

4.1 最佳实践

◆ 4.1.1 性能优化
  • • Worker进程与CPU绑定:防止进程在CPU之间切换导致缓存失效。
    # 在nginx.conf中配置
    worker_processes auto;
    worker_cpu_affinity auto;
    # 验证CPU绑定
    ps -eLo ruser,pid,ppid,lwp,psr,args | grep nginx | grep worker
    # psr列显示CPU编号,应该看到不同worker绑定不同CPU
  • • 内存优化:减少内存分配和拷贝。
    • 启用sendfile零拷贝:sendfile on;
    • 调整缓冲区大小:根据实际流量调整proxy_buffers
    • 使用共享内存:limit_req_zoneproxy_cache等使用共享内存
    • 监控内存使用:ps aux | grep nginx | awk '{sum+=$6} END {print sum/1024 "MB"}'
    • 避免内存泄漏:定期更新Nginx版本,修复已知bug
  • • 网络优化:减少延迟和提高吞吐。
    # 启用TCP Fast Open
    echo 3 > /proc/sys/net/ipv4/tcp_fastopen
    # Nginx配置中启用
    listen 80 fastopen=256;
    # 启用BBR拥塞控制
    echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
    sysctl -p
◆ 4.1.2 安全加固
  • • 限制请求速率和连接数:防止DDoS攻击和资源耗尽。
    # 基于IP的限流
    limit_req_zone $binary_remote_addr zone=req_zone:10m rate=10r/s;
    limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
    server {
    limit_req zone=req_zone burst=20 nodelay;
    limit_conn conn_zone 10;
    # 限制请求体大小
    client_max_body_size 10m;
    # 超时保护
    client_body_timeout 10s;
    client_header_timeout 10s;
    }
  • • 隐藏版本信息和敏感头。
    http {
    server_tokens off;
    more_clear_headers Server;  # 需要headers-more模块
    # 添加安全头
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    }
  • • SSL/TLS优化。
    server {
    listen 443 ssl http2;
    # 现代加密套件
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers on;
    # 会话复用
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    }
◆ 4.1.3 高可用配置
  • • Keepalived主备切换:实现Nginx高可用。
    # 安装Keepalived
    yum install -y keepalived
    # 主节点配置:/etc/keepalived/keepalived.conf
    cat > /etc/keepalived/keepalived.conf <<EOF
    vrrp_script check_nginx {
        script "/usr/local/bin/check_nginx.sh"
        interval 2
        weight -20
    }
    vrrp_instance VI_1 {
        state MASTER
        interface eth0
        virtual_router_id 51
        priority 100
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1234
        }
        virtual_ipaddress {
            192.168.1.100/24
        }
        track_script {
            check_nginx
        }
    }
    EOF
    # 健康检查脚本:/usr/local/bin/check_nginx.sh
    cat > /usr/local/bin/check_nginx.sh <<'EOF'
    #!/bin/bash
    if ! pgrep nginx > /dev/null; then
        systemctl start nginx
    sleep 2
    if ! pgrep nginx > /dev/null; then
    exit 1
    fi
    fi
    exit 0
    EOF
    chmod +x /usr/local/bin/check_nginx.sh
    # 启动Keepalived
    systemctl enable keepalived
    systemctl start keepalived
  • • LVS+Nginx集群架构:实现更大规模的负载均衡。
    • 前端:LVS(DR模式)分发到多台Nginx。
    • 中间:Nginx反向代理和缓存。
    • 后端:应用服务器集群。
  • • 备份策略:配置文件和日志备份。
    #!/bin/bash
    # 每日备份脚本:/usr/local/bin/nginx_backup.sh
    BACKUP_DIR="/backup/nginx/$(date +%Y%m%d)"
    mkdir -p $BACKUP_DIR
    # 备份配置文件
    tar -czf $BACKUP_DIR/nginx_conf.tar.gz /etc/nginx/
    # 备份日志(7天前的)
    find /var/log/nginx/ -name "*.log" -mtime +7 -exec gzip {} \;
    find /var/log/nginx/ -name "*.gz" -mtime +30 -exec mv {} $BACKUP_DIR/ \;
    # 清理30天前的备份
    find /backup/nginx/ -type d -mtime +30 -exec rm -rf {} \;
    # 加入crontab
    # 0 2 * * * /usr/local/bin/nginx_backup.sh

4.2 注意事项

◆ 4.2.1 配置注意事项

⚠️警告:修改系统内核参数和Nginx配置前务必备份,错误配置可能导致服务不可用或系统崩溃。

  • • ❗ worker_connections不要超过文件描述符限制:worker_connections 必须小于 worker_rlimit_nofile,否则无法建立足够的连接。
    # 检查当前限制
    ulimit -n
    cat /proc/$(pgrep nginx | head -1)/limits | grep "open files"
    # 确保:worker_connections < worker_rlimit_nofile < ulimit -n
  • • ❗ Keepalive连接池大小要合理:upstream的keepalive值应根据后端服务器数量和并发量设置。
    # 错误:keepalive设置过小,频繁建立连接
    upstream backend {
    server 10.0.1.11:8080;
    keepalive 10;  # 太小!
    }
    # 正确:根据并发量设置
    upstream backend {
    server 10.0.1.11:8080;
    keepalive 256;  # 推荐:每个后端server 128-512
    }
    # 客户端也要配置keepalive
    proxy_http_version 1.1;
    proxy_set_header Connection "";
  • • ❗ 日志写入会严重影响性能:百万并发场景建议关闭access_log或使用异步写入。
    # 方案1:完全关闭(推荐用于高并发)
    access_log off;
    # 方案2:缓冲写入
    access_log /var/log/nginx/access.log main buffer=128k flush=3s;
    # 方案3:采样记录(自定义模块)
    # if ($request_id ~ "^[0-9]$") {  # 10%采样
    #     access_log /var/log/nginx/access.log main;
    # }
◆ 4.2.2 常见错误
错误现象 原因分析 解决方案
connect() to ... failed (99: Cannot assign requested address) 客户端端口耗尽,TIME_WAIT状态连接过多 1. 启用tcp_tw_reuse<br>2. 扩大端口范围:net.ipv4.ip_local_port_range = 1024 65535<br>3. 缩短TIME_WAIT时间:tcp_fin_timeout = 15
worker_connections are not enough worker_connections设置过小 1. 增加worker_connections<br>2. 增加worker_processes<br>3. 检查并增加系统文件描述符限制
accept4() failed (24: Too many open files) 系统或进程文件描述符限制不足 1. 修改/etc/security/limits.conf<br>2. 增加worker_rlimit_nofile<br>3. 调整fs.file-max
upstream timed out (110: Connection timed out) 后端服务响应慢或无响应 1. 检查后端服务健康状况<br>2. 调整proxy_read_timeout<br>3. 启用proxy_next_upstream实现快速失败
no live upstreams while connecting to upstream 所有后端服务器不可用 1. 检查后端服务器状态<br>2. 调整健康检查参数max_failsfail_timeout<br>3. 配置backup服务器
could not build server_names_hash 域名哈希表配置不足 增加server_names_hash_bucket_sizeserver_names_hash_max_size
◆ 4.2.3 兼容性问题
  • • 版本兼容:
    • Nginx 1.18+:支持reuseport、线程池等高级特性。
    • Nginx 1.20+:改进HTTP/2性能。
    • Nginx 1.24+:支持HTTP/3(需编译ngx_http_v3_module)。
    • 建议使用主线版本(Mainline)以获得最新性能优化。
  • • 平台兼容:
    • CentOS/RHEL:/etc/nginx/
    • Ubuntu/Debian:/etc/nginx/
    • 编译安装:/usr/local/nginx/conf/
    • Linux系统:使用epoll事件模型(最高效)
    • FreeBSD:使用kqueue事件模型
    • Windows:性能较差,不建议用于生产环境
  • • 组件依赖:
    • OpenSSL版本:建议1.1.1+(支持TLS 1.3)
    • PCRE版本:8.4+(正则表达式)
    • zlib版本:1.2.11+(gzip压缩)
    • 如需HTTP/3支持,需要BoringSSL或Quiche

五、故障排查和监控

5.1 故障排查

◆ 5.1.1 日志查看
# 查看系统日志
sudo journalctl -u nginx -f
sudo journalctl -u nginx --since "10 minutes ago"
# 查看Nginx错误日志
tail -f /var/log/nginx/error.log
tail -100 /var/log/nginx/error.log | grep -i error
# 查看访问日志(分析慢请求)
tail -f /var/log/nginx/access.log
awk '{if($NF>1)print $0}' /var/log/nginx/access.log  # 响应时间>1秒
# 统计状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 统计IP访问频率(找出异常IP)
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# 统计请求URI TOP10
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# 分析响应时间分布
awk '{sum+=$NF; count+=1} END {print "平均响应时间:", sum/count, "秒"}' /var/log/nginx/access.log
◆ 5.1.2 常见问题排查

问题一:Nginx启动失败或无法绑定端口

# 诊断命令
nginx -t  # 测试配置文件语法
journalctl -u nginx -n 50  # 查看启动日志
ss -tlnp | grep :80  # 检查端口占用
setenforce 0  # 临时关闭SELinux测试
# 检查权限
ls -l /var/log/nginx/
ps aux | grep nginx

解决方案

  1. 使用nginx -t检查配置文件语法错误。
  2. 检查端口是否被其他进程占用:lsof -i :80
  3. 检查SELinux是否阻止:getenforce,临时关闭测试。
  4. 检查防火墙规则:iptables -L -n | grep 80
  5. 确认Nginx有权限访问日志目录和配置文件。

问题二:高并发场景下连接数上不去

# 诊断命令
# 查看当前连接数
ss -s
netstat -an | grep ESTABLISHED | wc -l
# 查看文件描述符使用情况
lsof -p $(pgrep nginx | head -1) | wc -l
cat /proc/$(pgrep nginx | head -1)/limits
# 检查系统限制
ulimit -n
sysctl fs.file-max
sysctl net.core.somaxconn
# 查看TIME_WAIT连接数
ss -tan | grep TIME_WAIT | wc -l

解决方案

  1. 增加系统文件描述符限制:echo "fs.file-max = 2097152" >> /etc/sysctl.conf
  2. 修改Nginx配置:增加worker_connectionsworker_rlimit_nofile
  3. 启用TIME_WAIT复用:sysctl -w net.ipv4.tcp_tw_reuse=1
  4. 扩大端口范围:sysctl -w net.ipv4.ip_local_port_range="1024 65535"
  5. 重启Nginx使配置生效。

问题三:反向代理后端连接失败

  • • 症状:502/504错误频繁出现,错误日志显示upstream timed out
  • • 排查:
    # 检查后端服务器状态
    curl -I http://backend_server:8080/health
    telnet backend_server 8080
    # 检查网络连通性
    ping backend_server
    traceroute backend_server
    # 检查防火墙规则
    iptables -L -n | grep 8080
    # 查看Nginx到后端的连接数
    netstat -an | grep :8080 | grep ESTABLISHED | wc -l
    # 查看后端服务器负载
    ssh backend_server "uptime; free -h; iostat"
  • • 解决:
    1. 检查后端服务是否正常运行:systemctl status backend_app
    2. 调整超时参数:增加proxy_read_timeoutproxy_connect_timeout
    3. 检查后端服务器性能瓶颈(CPU、内存、IO)。
    4. 启用健康检查,自动摘除故障节点。
    5. 配置失败重试:proxy_next_upstream error timeout
◆ 5.1.3 调试模式
# 临时开启调试日志(会产生大量日志,仅用于故障诊断)
# 修改nginx.conf
error_log /var/log/nginx/debug.log debug;
# 或仅对特定IP开启调试
events {
    debug_connection 192.168.1.100;
}
# 重载配置
nginx -s reload
# 查看调试信息
tail -f /var/log/nginx/debug.log
# 使用strace跟踪系统调用(高级诊断)
strace -p $(pgrep nginx | head -1) -e trace=network -s 1024
# 使用gdb调试core dump
# 启用core dump
ulimit -c unlimited
echo "/tmp/core.%e.%p" > /proc/sys/kernel/core_pattern
# 分析core文件
gdb /usr/sbin/nginx /tmp/core.nginx.12345
(gdb) bt  # 查看堆栈
# 性能分析工具perf
perf top -p $(pgrep nginx | head -1)
perf record -p $(pgrep nginx | head -1) -g -- sleep 10
perf report

5.2 性能监控

◆ 5.2.1 关键指标监控
# CPU使用率(按worker进程)
top -p $(pgrep nginx | tr '\n' ',' | sed 's/,$//')
# 内存使用详情
ps aux | grep nginx
pmap -x $(pgrep nginx | head -1)
# 网络连接状态
ss -tan | awk '{print $1}' | sort | uniq -c
netstat -s | grep -i "segments retransmited"
# 磁盘IO(日志和缓存)
iostat -x 1 10
iotop -p $(pgrep nginx | tr '\n' ',' | sed 's/,$//')
# 实时QPS监控
tail -f /var/log/nginx/access.log | pv -l -i 1 -r > /dev/null
# Nginx状态页面
curl http://localhost/nginx_status
# Active connections: 2891
# server accepts handled requests
#  1234567 1234567 8901234
# Reading: 10 Writing: 20 Keeping: 2861
# 解析stub_status输出脚本
cat > /usr/local/bin/nginx_stats.sh <<'EOF'
#!/bin/bash
URL="http://localhost/nginx_status"
curl -s $URL | awk '
NR==1 {print "活跃连接数:", $3}
NR==3 {print "总接受连接:", $1; print "总处理连接:", $2; print "总请求数:", $3}
NR==4 {print "读取请求:", $2; print "写入响应:", $4; print "等待请求:", $6}'
EOF
chmod +x /usr/local/bin/nginx_stats.sh
◆ 5.2.2 监控指标说明
指标名称 正常范围 告警阈值 说明
CPU使用率 40-70% >85% 单核CPU使用率持续超过85%需要扩容
内存使用 <80% >90% 包括共享内存(缓存、限流区域)
活跃连接数 视业务 >worker_connections*80% 接近上限时可能拒绝新连接
QPS 视业务 突降50% 可能服务异常或上游故障
响应时间P99 <500ms >2s 99%请求响应时间,超过阈值影响体验
5xx错误率 <0.1% >1% 后端服务异常或超时
TIME_WAIT连接数 <50000 >100000 过多说明连接复用不足
文件描述符使用率 <70% >85% 接近上限会导致无法建立新连接
◆ 5.2.3 监控告警配置

使用Prometheus + Grafana监控

# 安装nginx-prometheus-exporter
# 下载地址:https://github.com/nginxinc/nginx-prometheus-exporter
# 启动exporter
./nginx-prometheus-exporter -nginx.scrape-uri=http://localhost/nginx_status
# Prometheus配置:prometheus.yml
scrape_configs:
- job_name: 'nginx'
  static_configs:
  - targets: ['localhost:9113']
    labels:
      instance: 'nginx-server-1'
      environment: 'production'
  scrape_interval: 15s
# 告警规则:nginx_alerts.yml
groups:
- name: nginx_alerts
  interval: 30s
  rules:
  # CPU使用率告警
  - alert: NginxHighCPU
    expr: rate(process_cpu_seconds_total{job="nginx"}[5m]) > 0.8
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Nginx CPU使用率过高"
      description: "实例 {{ $labels.instance }} CPU使用率 {{ $value | humanizePercentage }}"
  # 5xx错误率告警
  - alert: NginxHigh5xxRate
    expr: rate(nginx_http_requests_total{status=~"5.."}[5m]) / rate(nginx_http_requests_total[5m]) > 0.01
    for: 2m
    labels:
      severity: critical
    annotations:
      summary: "Nginx 5xx错误率过高"
      description: "实例 {{ $labels.instance }} 5xx错误率 {{ $value | humanizePercentage }}"
  # 连接数告警
  - alert: NginxHighConnections
    expr: nginx_connections_active > 50000
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Nginx活跃连接数过高"
      description: "实例 {{ $labels.instance }} 活跃连接数 {{ $value }}"
  # 响应时间告警
  - alert: NginxSlowResponse
    expr: histogram_quantile(0.99, rate(nginx_http_request_duration_seconds_bucket[5m])) > 2
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Nginx响应时间过慢"
      description: "实例 {{ $labels.instance }} P99响应时间 {{ $value }}秒"

使用Zabbix监控

# Zabbix Agent配置:/etc/zabbix/zabbix_agentd.d/nginx.conf
UserParameter=nginx.connections.active,curl -s http://localhost/nginx_status | awk 'NR==1 {print $3}'
UserParameter=nginx.connections.reading,curl -s http://localhost/nginx_status | awk 'NR==4 {print $2}'
UserParameter=nginx.connections.writing,curl -s http://localhost/nginx_status | awk 'NR==4 {print $4}'
UserParameter=nginx.connections.waiting,curl -s http://localhost/nginx_status | awk 'NR==4 {print $6}'
UserParameter=nginx.accepts,curl -s http://localhost/nginx_status | awk 'NR==3 {print $1}'
UserParameter=nginx.handled,curl -s http://localhost/nginx_status | awk 'NR==3 {print $2}'
UserParameter=nginx.requests,curl -s http://localhost/nginx_status | awk 'NR==3 {print $3}'
# 重启zabbix agent
systemctl restart zabbix-agent

自定义监控脚本(结合Telegraf)

#!/bin/bash
# 文件名:/usr/local/bin/nginx_metrics.sh
# 输出InfluxDB Line Protocol格式
NGINX_STATUS=$(curl -s http://localhost/nginx_status)
TIMESTAMP=$(date +%s)000000000
# 解析数据
ACTIVE=$(echo "$NGINX_STATUS" | awk 'NR==1 {print $3}')
ACCEPTS=$(echo "$NGINX_STATUS" | awk 'NR==3 {print $1}')
HANDLED=$(echo "$NGINX_STATUS" | awk 'NR==3 {print $2}')
REQUESTS=$(echo "$NGINX_STATUS" | awk 'NR==3 {print $3}')
READING=$(echo "$NGINX_STATUS" | awk 'NR==4 {print $2}')
WRITING=$(echo "$NGINX_STATUS" | awk 'NR==4 {print $4}')
WAITING=$(echo "$NGINX_STATUS" | awk 'NR==4 {print $6}')
# 输出metrics
echo "nginx_connections,host=$(hostname) active=${ACTIVE}i,reading=${READING}i,writing=${WRITING}i,waiting=${WAITING}i ${TIMESTAMP}"
echo "nginx_stats,host=$(hostname) accepts=${ACCEPTS}i,handled=${HANDLED}i,requests=${REQUESTS}i ${TIMESTAMP}"
# Telegraf配置:/etc/telegraf/telegraf.d/nginx.conf
# [[inputs.exec]]
#   commands = ["/usr/local/bin/nginx_metrics.sh"]
#   data_format = "influx"
#   interval = "10s"

5.3 备份与恢复

◆ 5.3.1 备份策略
#!/bin/bash
# 完整的Nginx备份脚本
# 文件名:/usr/local/bin/nginx_full_backup.sh
set -e

# 配置变量
BACKUP_ROOT="/backup/nginx"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="${BACKUP_ROOT}/${DATE}"
RETENTION_DAYS=30

# 创建备份目录
mkdir -p "${BACKUP_DIR}"
echo "========== Nginx完整备份开始 =========="
echo "备份目录: ${BACKUP_DIR}"
echo "时间: $(date)"

# 1. 备份配置文件
echo "正在备份配置文件..."
tar -czf "${BACKUP_DIR}/nginx_config.tar.gz" \
    /etc/nginx/ \
    /usr/local/nginx/conf/ 2>/dev/null || true

# 2. 备份SSL证书
echo "正在备份SSL证书..."
if [ -d /etc/nginx/ssl ]; then
    tar -czf "${BACKUP_DIR}/nginx_ssl.tar.gz" /etc/nginx/ssl/
fi

# 3. 备份自定义脚本
echo "正在备份自定义脚本..."
tar -czf "${BACKUP_DIR}/nginx_scripts.tar.gz" \
    /usr/local/bin/*nginx* 2>/dev/null || true

# 4. 备份日志(最近7天)
echo "正在备份日志文件..."
find /var/log/nginx/ -name "*.log" -mtime -7 -exec tar -czf "${BACKUP_DIR}/nginx_logs.tar.gz" {} +

# 5. 导出当前运行状态
echo "正在导出运行状态..."
{
echo "===== Nginx版本 ====="
    nginx -V 2>&1
echo ""
echo "===== 运行状态 ====="
    systemctl status nginx --no-page
echo ""
echo "===== 进程信息 ====="
    ps aux | grep nginx
echo ""
echo "===== 连接统计 ====="
    ss -s
echo ""
echo "===== 配置测试 ====="
    nginx -t 2>&1
} > "${BACKUP_DIR}/nginx_status.txt"

# 6. 备份缓存元数据(可选)
if [ -d /data/nginx/cache ]; then
echo "正在备份缓存元数据..."
    find /data/nginx/cache -name "*.meta" -exec tar -czf "${BACKUP_DIR}/cache_metadata.tar.gz" {} + 2>/dev/null || true
fi

# 7. 创建备份清单
echo "正在生成备份清单..."
{
echo "Nginx备份清单"
echo "备份时间: $(date)"
echo "主机名: $(hostname)"
echo "Nginx版本: $(nginx -v 2>&1)"
echo ""
echo "备份文件列表:"
ls -lh "${BACKUP_DIR}/"
echo ""
echo "总大小: $(du -sh ${BACKUP_DIR} | awk '{print $1}')"
} > "${BACKUP_DIR}/backup_manifest.txt"

# 8. 生成MD5校验
echo "正在生成MD5校验..."
cd "${BACKUP_DIR}"
md5sum *.tar.gz > checksums.md5

# 9. 清理旧备份
echo "正在清理${RETENTION_DAYS}天前的备份..."
find "${BACKUP_ROOT}" -type d -mtime +${RETENTION_DAYS} -exec rm -rf {} + 2>/dev/null || true

# 10. 备份到远程(可选)
# echo "正在同步到远程备份服务器..."
# rsync -avz "${BACKUP_DIR}" backup-server:/backup/nginx/

echo "========== 备份完成 =========="
echo "备份位置: ${BACKUP_DIR}"
echo "备份大小: $(du -sh ${BACKUP_DIR} | awk '{print $1}')"

# 发送通知(可选)
# curl -X POST -H 'Content-Type: application/json' \
#   -d "{\"text\":\"Nginx备份完成: ${BACKUP_DIR}\"}" \
#   https://hooks.slack.com/services/YOUR/WEBHOOK/URL

exit 0

定时备份配置

# 添加到crontab
crontab -e
# 每天凌晨2点执行备份
0 2 * * * /usr/local/bin/nginx_full_backup.sh >> /var/log/nginx_backup.log 2>&1
# 每周日凌晨3点执行完整备份并同步到远程
0 3 * * 0 /usr/local/bin/nginx_full_backup.sh --remote >> /var/log/nginx_backup.log 2>&1
◆ 5.3.2 恢复流程
#!/bin/bash
# Nginx恢复脚本
# 文件名:/usr/local/bin/nginx_restore.sh
set -e

if [ -z "$1" ]; then
echo "用法: $0 <备份目录>"
echo "示例: $0 /backup/nginx/20250115_020000"
exit 1
fi

BACKUP_DIR="$1"
if [ ! -d "$BACKUP_DIR" ]; then
echo "错误: 备份目录不存在: $BACKUP_DIR"
exit 1
fi

echo "========== Nginx恢复流程 =========="
echo "备份目录: $BACKUP_DIR"
echo "开始时间: $(date)"

# 验证备份完整性
echo "正在验证备份文件完整性..."
cd "$BACKUP_DIR"
if [ -f checksums.md5 ]; then
md5sum -c checksums.md5 || {
echo "错误: 备份文件校验失败!"
exit 1
    }
echo "校验通过"
else
echo "警告: 未找到校验文件,跳过完整性验证"
fi

# 1. 停止Nginx服务
echo "正在停止Nginx服务..."
systemctl stop nginx || true
sleep 2

# 2. 备份当前配置(以防恢复失败)
CURRENT_BACKUP="/tmp/nginx_current_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$CURRENT_BACKUP"
cp -r /etc/nginx/ "$CURRENT_BACKUP/" 2>/dev/null || true
echo "当前配置已备份到: $CURRENT_BACKUP"

# 3. 恢复配置文件
echo "正在恢复配置文件..."
if [ -f "$BACKUP_DIR/nginx_config.tar.gz" ]; then
    tar -xzf "$BACKUP_DIR/nginx_config.tar.gz" -C /
echo "配置文件恢复完成"
else
echo "警告: 未找到配置文件备份"
fi

# 4. 恢复SSL证书
echo "正在恢复SSL证书..."
if [ -f "$BACKUP_DIR/nginx_ssl.tar.gz" ]; then
    tar -xzf "$BACKUP_DIR/nginx_ssl.tar.gz" -C /
echo "SSL证书恢复完成"
fi

# 5. 恢复自定义脚本
echo "正在恢复自定义脚本..."
if [ -f "$BACKUP_DIR/nginx_scripts.tar.gz" ]; then
    tar -xzf "$BACKUP_DIR/nginx_scripts.tar.gz" -C /
chmod +x /usr/local/bin/*nginx* 2>/dev/null || true
echo "自定义脚本恢复完成"
fi

# 6. 测试配置文件
echo "正在测试配置文件..."
nginx -t || {
echo "错误: 配置文件测试失败!正在回滚..."
cp -r "$CURRENT_BACKUP/nginx/"* /etc/nginx/
echo "已回滚到恢复前配置"
exit 1
}

# 7. 重启Nginx服务
echo "正在启动Nginx服务..."
systemctl start nginx
sleep 3

# 8. 验证服务状态
echo "正在验证服务状态..."
if systemctl is-active --quiet nginx; then
echo "Nginx服务运行正常"
    curl -s http://localhost/nginx_status || echo "警告: 无法访问状态页面"
else
echo "错误: Nginx服务启动失败!"
    journalctl -u nginx -n 50 --no-page
exit 1
fi

# 9. 恢复完成
echo "========== 恢复完成 =========="
echo "备份目录: $BACKUP_DIR"
echo "完成时间: $(date)"
echo "当前配置备份: $CURRENT_BACKUP (如确认无误可删除)"

# 清理临时文件(可选)
# rm -rf "$CURRENT_BACKUP"
exit 0

恢复操作步骤

  1. 停止服务:systemctl stop nginx
  2. 恢复数据:/usr/local/bin/nginx_restore.sh /backup/nginx/20250115_020000
  3. 验证完整性:nginx -t
  4. 重启服务:systemctl start nginx
  5. 验证功能:curl -I http://localhost/

六、总结

6.1 技术要点回顾

  • • 并发处理能力优化:通过调整worker_processesworker_connections和系统文件描述符限制,理论并发从默认的几千提升到100万级别。核心公式:最大并发 = worker_processes × worker_connections
  • • 内核参数调优:Linux内核参数对高并发性能至关重要,重点优化TCP协议栈(somaxconntcp_max_syn_backlogtcp_tw_reuse)、连接跟踪(nf_conntrack_max)和BBR拥塞控制算法。
  • • Keepalive长连接优化:客户端和上游服务器的Keepalive配置能大幅减少连接建立开销,keepalive_requests建议设置为1000-10000,upstream的keepalive连接池建议每个后端server配置128-512。
  • • 缓存和压缩策略:合理使用proxy_cacheopen_file_cache可减少后端压力和磁盘IO,gzip压缩在高并发场景应适当降低压缩级别(4-5)以平衡CPU消耗。

6.2 进阶学习方向

  1. HTTP/3和QUIC协议:下一代HTTP协议,基于UDP实现更快的连接建立和更好的丢包恢复。
    • 学习资源:Nginx官方HTTP/3文档、Cloudflare QUIC博客。
    • 实践建议:在测试环境编译启用HTTP/3模块,对比HTTP/2性能差异。
  2. Nginx动态模块和OpenResty:扩展Nginx功能,使用Lua脚本实现复杂业务逻辑。
    • 学习资源:OpenResty官方文档、Lua-Nginx-Module GitHub。
    • 实践建议:学习使用Lua实现动态路由、限流、A/B测试等高级功能。
  3. Nginx Plus商业版高级特性:动态配置、高级健康检查、会话持久化、实时监控API。
    • 学习资源:Nginx Plus官方文档。
    • 实践建议:评估商业版功能与开源版差异,决定是否采用。
  4. Service Mesh和云原生架构:在Kubernetes环境中部署Nginx Ingress Controller,可以参考云原生相关的最佳实践。
    • 学习资源:Nginx Ingress Controller文档。
    • 实践建议:学习K8s环境下的Nginx配置管理、自动扩缩容、灰度发布。

6.3 参考资料

附录

A. 命令速查表

# ========== 常用运维命令 ==========
# 配置管理
nginx -t                          # 测试配置文件语法
nginx -T                          # 测试并打印完整配置
nginx -s reload                   # 平滑重载配置
nginx -s reopen                   # 重新打开日志文件
nginx -s stop                     # 快速停止
nginx -s quit                     # 优雅停止
nginx -V                          # 查看编译参数和版本

# 进程管理
systemctl start nginx             # 启动服务
systemctl stop nginx              # 停止服务
systemctl restart nginx           # 重启服务
systemctl reload nginx            # 重载配置
systemctl status nginx            # 查看状态
systemctl enable nginx            # 设置开机自启

# 性能监控
curl http://localhost/nginx_status  # 查看状态页
ss -tan | grep ESTABLISHED | wc -l  # 统计连接数
ss -s                                # 连接统计摘要
lsof -p $(pgrep nginx | head -1) | wc -l  # 文件描述符数量
top -p $(pgrep nginx | tr '\n' ',' | sed 's/,$//')  # CPU和内存

# 日志分析
tail -f /var/log/nginx/access.log                    # 实时查看访问日志
awk '{print $9}' access.log | sort | uniq -c        # 状态码统计
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20  # TOP20 IP
awk '{sum+=$NF;count++} END {print sum/count}' access.log  # 平均响应时间

# 压力测试
ab -n 100000 -c 1000 http://localhost/              # Apache Bench
wrk -t12 -c400 -d30s http://localhost/              # wrk测试
siege -c 1000 -r 100 http://localhost/              # Siege测试

# 系统调优
ulimit -n 1048576                 # 临时调整文件描述符
sysctl -w net.core.somaxconn=65535  # 临时调整内核参数
sysctl -p                         # 应用sysctl配置
sysctl -a | grep tcp              # 查看所有TCP参数

B. 配置参数详解

worker进程相关

  • • worker_processes auto:worker进程数,建议设置为CPU核心数。
  • • worker_cpu_affinity auto:自动绑定worker到CPU核心。
  • • worker_rlimit_nofile 1048576:单个worker最大文件描述符数。
  • • worker_priority -10:进程优先级(-20到19,数值越小优先级越高)。
  • • worker_shutdown_timeout 30s:worker优雅退出超时时间。

事件模块参数

  • • use epoll:事件驱动模型(Linux用epoll,FreeBSD用kqueue)。
  • • worker_connections 65535:单个worker最大并发连接数。
  • • multi_accept on:一次accept尽可能多的连接。
  • • accept_mutex off:关闭互斥锁(高并发推荐)。

HTTP核心参数

  • • sendfile on:启用零拷贝技术。
  • • tcp_nopush on:数据包累积发送(需sendfile开启)。
  • • tcp_nodelay on:禁用Nagle算法,立即发送小包。
  • • keepalive_timeout 65:客户端连接保持时间(秒)。
  • • keepalive_requests 1000:单个连接最大请求数。
  • • reset_timedout_connection on:重置超时连接,释放内存。

缓冲区参数

  • • client_body_buffer_size 256k:客户端请求体缓冲区。
  • • client_header_buffer_size 4k:客户端请求头缓冲区。
  • • large_client_header_buffers 4 32k:大请求头缓冲区。
  • • proxy_buffer_size 8k:代理缓冲区大小。
  • • proxy_buffers 32 8k:代理缓冲区数量和大小。
  • • proxy_busy_buffers_size 64k:忙碌缓冲区大小。

超时参数

  • • client_header_timeout 15s:读取客户端请求头超时。
  • • client_body_timeout 15s:读取客户端请求体超时。
  • • send_timeout 60s:发送响应超时。
  • • proxy_connect_timeout 5s:连接后端超时。
  • • proxy_send_timeout 60s:发送到后端超时。
  • • proxy_read_timeout 60s:读取后端响应超时。

限流参数

  • • limit_req_zone $binary_remote_addr zone=name:10m rate=10r/s:请求限流区域。
  • • limit_req zone=name burst=20 nodelay:应用限流(burst允许突发)。
  • • limit_conn_zone $binary_remote_addr zone=name:10m:连接限流区域。
  • • limit_conn name 10:单IP最大连接数。
  • • limit_rate 500k:限制响应速率(每秒字节数)。

Gzip压缩参数

  • • gzip on:启用gzip压缩。
  • • gzip_comp_level 6:压缩级别(1-9,6为推荐值)。
  • • gzip_min_length 1000:最小压缩文件大小(字节)。
  • • gzip_types text/plain text/css application/json:压缩MIME类型。
  • • gzip_vary on:添加Vary: Accept-Encoding响应头。
  • • gzip_proxied any:代理请求也压缩。

缓存参数

  • • proxy_cache_path /path levels=1:2 keys_zone=name:100m max_size=10g inactive=60m:缓存路径配置。
  • • proxy_cache name:启用缓存。
  • • proxy_cache_key $scheme$host$uri$is_args$args:缓存键。
  • • proxy_cache_valid 200 304 1h:缓存有效期。
  • • proxy_cache_use_stale error timeout updating:过期缓存仍可用的场景。
  • • proxy_cache_lock on:缓存锁防止缓存击穿。

C. 术语表

术语 英文 解释
事件驱动 Event-Driven Nginx核心架构,使用epoll/kqueue等机制异步处理I/O事件,无需为每个连接创建线程
零拷贝 Zero-Copy sendfile系统调用,数据直接在内核空间传输,无需拷贝到用户空间,提升性能
工作进程 Worker Process Nginx的工作进程,实际处理请求,通常设置为CPU核心数
主进程 Master Process Nginx的主控进程,负责管理worker进程、读取配置、绑定端口
上游服务器 Upstream Server Nginx反向代理的后端服务器,也称为backend或origin server
长连接 Keep-Alive HTTP持久连接,复用TCP连接发送多个请求,减少握手开销
反向代理 Reverse Proxy Nginx代理客户端请求到后端服务器,客户端无法直接访问后端
负载均衡 Load Balancing 将请求分发到多个后端服务器,常见算法:轮询、最少连接、IP哈希
限流 Rate Limiting 限制单位时间内的请求数或连接数,防止滥用和过载
缓存击穿 Cache Stampede 热点缓存失效时,大量请求同时打到后端,使用proxy_cache_lock解决
QPS Queries Per Second 每秒查询数,衡量系统吞吐量的指标
并发连接数 Concurrent Connections 同时保持的活跃连接数量
文件描述符 File Descriptor Linux中代表打开文件或网络连接的整数句柄,高并发需大量FD
TIME_WAIT TIME_WAIT State TCP连接关闭后的等待状态(默认60秒),过多会耗尽端口资源
BBR Bottleneck Bandwidth and RTT Google开发的TCP拥塞控制算法,提升弱网环境下的吞吐量
Epoll Event Poll Linux高效的I/O多路复用机制,支持百万级并发连接
健康检查 Health Check 定期检测后端服务器状态,自动摘除故障节点
会话保持 Session Persistence 同一客户端的请求始终转发到同一后端服务器(如ip_hash
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区(YunPan.Plus) ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-3 14:50 , Processed in 0.072111 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 CloudStack.

快速回复 返回顶部 返回列表