一、概述
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配置以应对流量洪峰。
实现步骤:
- 硬件准备:32核CPU、64GB内存、万兆网卡
- 内核参数调优:调整TCP参数和连接跟踪表
- 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网关,需要实现限流、熔断、负载均衡功能,这是构建稳健后端架构的关键组件。
实现步骤:
- 配置多级限流策略(IP级、API级)。
- 实现健康检查和自动摘除故障节点。
- 配置不同的负载均衡算法。
配置文件:
# 文件路径:/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_zone、proxy_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_fails和fail_timeout<br>3. 配置backup服务器 |
could not build server_names_hash |
域名哈希表配置不足 |
增加server_names_hash_bucket_size和server_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
解决方案:
- 使用
nginx -t检查配置文件语法错误。
- 检查端口是否被其他进程占用:
lsof -i :80。
- 检查SELinux是否阻止:
getenforce,临时关闭测试。
- 检查防火墙规则:
iptables -L -n | grep 80。
- 确认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
解决方案:
- 增加系统文件描述符限制:
echo "fs.file-max = 2097152" >> /etc/sysctl.conf。
- 修改Nginx配置:增加
worker_connections和worker_rlimit_nofile。
- 启用TIME_WAIT复用:
sysctl -w net.ipv4.tcp_tw_reuse=1。
- 扩大端口范围:
sysctl -w net.ipv4.ip_local_port_range="1024 65535"。
- 重启Nginx使配置生效。
问题三:反向代理后端连接失败
◆ 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
恢复操作步骤:
- 停止服务:
systemctl stop nginx
- 恢复数据:
/usr/local/bin/nginx_restore.sh /backup/nginx/20250115_020000
- 验证完整性:
nginx -t
- 重启服务:
systemctl start nginx
- 验证功能:
curl -I http://localhost/
六、总结
6.1 技术要点回顾
- • 并发处理能力优化:通过调整
worker_processes、worker_connections和系统文件描述符限制,理论并发从默认的几千提升到100万级别。核心公式:最大并发 = worker_processes × worker_connections。
- • 内核参数调优:Linux内核参数对高并发性能至关重要,重点优化TCP协议栈(
somaxconn、tcp_max_syn_backlog、tcp_tw_reuse)、连接跟踪(nf_conntrack_max)和BBR拥塞控制算法。
- • Keepalive长连接优化:客户端和上游服务器的Keepalive配置能大幅减少连接建立开销,
keepalive_requests建议设置为1000-10000,upstream的keepalive连接池建议每个后端server配置128-512。
- • 缓存和压缩策略:合理使用
proxy_cache、open_file_cache可减少后端压力和磁盘IO,gzip压缩在高并发场景应适当降低压缩级别(4-5)以平衡CPU消耗。
6.2 进阶学习方向
- HTTP/3和QUIC协议:下一代HTTP协议,基于UDP实现更快的连接建立和更好的丢包恢复。
- 学习资源:Nginx官方HTTP/3文档、Cloudflare QUIC博客。
- 实践建议:在测试环境编译启用HTTP/3模块,对比HTTP/2性能差异。
- Nginx动态模块和OpenResty:扩展Nginx功能,使用Lua脚本实现复杂业务逻辑。
- 学习资源:OpenResty官方文档、Lua-Nginx-Module GitHub。
- 实践建议:学习使用Lua实现动态路由、限流、A/B测试等高级功能。
- Nginx Plus商业版高级特性:动态配置、高级健康检查、会话持久化、实时监控API。
- 学习资源:Nginx Plus官方文档。
- 实践建议:评估商业版功能与开源版差异,决定是否采用。
- 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) |