Nginx中Master与Worker进程的工作机制

描述

背景与目的

Nginx是现代互联网架构中最常用的Web服务器和反向代理软件。很多运维工程师使用Nginx多年,却对其核心架构一知半解,配置优化时只会机械地调整几个参数。本文从Nginx进程模型出发,深入讲解worker进程的工作机制,帮助你理解每个配置参数背后的原理,实现真正有效的优化。

前置知识:本文假设你已经具备Linux基础操作能力,了解Web服务器的基本概念,有过实际部署和维护Nginx的经验。

环境说明:本文基于Nginx 1.26.x(主线版本),操作系统Rocky Linux 9.4,OpenSSL 3.2.x。

1. Nginx进程模型解析

1.1 进程架构概述

Nginx采用多进程架构,而非多线程架构。这是刻意设计的选择,有以下优势:

master进程:主进程,负责以下工作:

读取和验证配置文件

管理worker进程(启动、停止、重启)

接收外部信号(如nginx -s reload)

处理热部署(热升级)

worker进程:工作进程,实际处理请求:

接收客户端连接

处理HTTP请求

与后端服务器通信(反向代理)

缓存处理

日志写入

cache loader和cache manager:仅在启用缓存时存在

cache loader:加载缓存元数据到内存

cache manager:管理缓存过期和清理

 

# 查看Nginx进程结构
$ ps aux | grep nginx

root     12345  0.0  0.1  123456  4567   ?  Ss   10:00   0:00  nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    12346  0.0  0.2  234567  8901   ?  S    10:00   0:02  nginx: worker process
nginx    12347  0.0  0.2  234567  8902   ?  S    10:00   0:02  nginx: worker process
nginx    12348  0.0  0.2  234567  8903   ?  S    10:00   0:02  nginx: worker process
nginx    12349  0.0  0.2  234567  8904   ?  S    10:00   0:01  nginx: worker process

# 进程关系图
#
#            [master process]
#                 |
#     +-----------+-----------+
#     |           |           |
#  [worker]   [worker]   [worker]  ...
#     |           |           |
#   (CPU)      (CPU)      (CPU)
#
#  所有worker进程共享同一个监听端口

 

1.2 为什么选择多进程而非多线程

多线程的问题

共享地址空间,线程安全问题复杂

一个线程崩溃可能影响整个进程

内存同步开销大

调试困难

多进程的优势

worker进程完全独立,互不影响

一个worker崩溃不会影响其他worker

每个worker可以独立运行在多核CPU上

简化内存管理(进程间不共享内存)

惊群问题(Thundering Herd)

旧版Nginx存在惊群问题:一个连接到来时所有worker被唤醒,但只有1个能抢到

Nginx 1.11.3+通过socket sharding解决此问题

现代Nginx使用SO_REUSEPORT,允许内核层面分发连接

1.3 连接处理模型

Nginx使用事件驱动架构,基于I/O多路复用(Linux上是epoll,FreeBSD是kqueue)。

 

# 查看Nginx事件模型
$ nginx -V 2>&1 | grep -o 'with-.*'

with-http_ssl_module
with-http_v2_module
with-http_realip_module
with-http_image_filter_module
...

# 查看系统支持的事件模型
$ cat /proc/sys/fs/inotify/max_user_watches

 

请求处理流程

 

Client Request
      |
      v
[Master Process] --listen()--> Port 80/443
      |
      v
[Kernel accepts connection]
      |
      v
[epoll/kqueue notifies ONE worker]
      |
      v
[Worker processes request]
      |
      +--> Static file (direct sendfile)
      |
      +--> Proxy to backend (uwsgi/fastcgi/http)
      |
      +--> Memcached
      |
      +--> gRPC
      |
      v
Response to Client

 

2. worker_processes与CPU核心绑定

2.1 worker_processes配置

worker_processes指令控制worker进程数量。

 

# 自动检测CPU核心数(推荐配置)
worker_processes auto;

# 固定值
worker_processes 4;

# 查看CPU核心数
$ nproc
8

# 查看CPU详细信息
$ lscpu

 

最佳实践

生产环境建议使用auto,让Nginx自动匹配CPU核心数

如果有多个Nginx实例在不同端口,不要让总数超过CPU核心数

绑定到特定CPU核心:worker_cpu_affinity

2.2 worker_cpu_affinity绑定

将worker进程绑定到特定CPU核心,避免进程切换开销。

 

# 4核心CPU绑定示例
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;

# 8核心CPU绑定示例
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

# 8核心但只有4个worker
worker_processes 4;
worker_cpu_affinity 00010001 00100010 01000100 10001000;

 

验证绑定效果

 

# 查看进程CPU亲和性
$ ps -eo pid,psr,comm | grep nginx
12346  0  nginx
12347  1  nginx
12348  2  nginx
12349  3  nginx

# PSR列表示当前运行的CPU核心

 

2.3 worker_priority调整

 

# 设置worker进程优先级(-20到20,越低优先级越高)
# 默认-15到15,设置为负数获得更高优先级
worker_priority -10;

 

2.4 worker_rlimit_nofile

设置单个worker进程能打开的最大文件描述符数量。

 

# 系统级限制
# /etc/security/limits.conf
# * soft nofile 65535
# * hard nofile 65535

worker_rlimit_nofile 65535;

 

文件描述符消耗来源

客户端连接(每个连接1个fd)

upstream连接池

打开的缓存文件

打开的日志文件

 

# 查看系统级文件描述符限制
$ cat /proc/sys/fs/file-max

# 查看当前使用量
$ cat /proc/sys/fs/file-nr
1024    0       65535
# 已分配   分配中   最大值

# 查看单个进程限制
$ cat /proc/12346/limits

 

3. worker_connections与并发控制

3.1 worker_connections详解

每个worker进程能处理的最大并发连接数。

 

events {
    # 默认512,生产环境通常设置更高
    worker_connections 1024;

    # 使用epoll(Linux默认)
    use epoll;

    # 启用异步I/O
    # aio on;

    # 多路复用accept(减少惊群)
    multi_accept on;
}

 

理论最大并发计算

 

# 最大并发 = worker_processes * worker_connections
# 但实际上还要考虑:
# 1. 每个连接占用文件描述符
# 2. 浏览器通常每个域名2-8个并发连接
# 3. 反向代理时upstream连接也要占用fd

# 例如:
# worker_processes = 4
# worker_connections = 1024
# 最大并发 = 4 * 1024 = 4096
# 但反向代理时需要预留一半给upstream:
# 实际可处理客户端连接 = 2048

 

3.2 最大连接数计算

 

# nginx.conf
worker_processes auto;
worker_connections 4096;

# 计算公式
# 最大TCP连接数 = worker_processes * worker_connections
# 最大并发客户端 = 最大TCP连接数 / 2(HTTP Keep-Alive)

 

3.3 实际配置示例

 

# 通用Web服务器配置
worker_processes auto;
worker_connections 4096;
worker_rlimit_nofile 65535;

events {
    use epoll;
    multi_accept on;
    worker_connections 4096;
}
# 高并发静态资源服务器
worker_processes auto;
worker_connections 16384;
worker_rlimit_nofile 262144;

events {
    use epoll;
    multi_accept on;
    worker_connections 16384;
}
# 反向代理服务器(需要预留upstream连接)
worker_processes auto;
worker_connections 8192;
worker_rlimit_nofile 32768;

events {
    use epoll;
    multi_accept on;
}

 

4. upstream负载均衡策略

4.1 轮询(round_robin)

默认策略,按顺序依次分发请求。

 

upstream backend {
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
    server 192.168.1.103:8080;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

 

4.2 加权轮询(weight)

根据权重比例分发请求,适合后端性能不均的场景。

 

upstream backend {
    server 192.168.1.101:8080 weight=5;    # 5/15 = 33%
    server 192.168.1.102:8080 weight=5;    # 5/15 = 33%
    server 192.168.1.103:8080 weight=5;    # 5/15 = 33%
}

# 或者后端性能强的多分配
upstream backend {
    server 192.168.1.101:8080 weight=3;   # 3/6 = 50%
    server 192.168.1.102:8080 weight=2;    # 2/6 = 33%
    server 192.168.1.103:8080 weight=1;    # 1/6 = 17%
}

 

4.3 IP哈希(ip_hash)

同一IP的请求始终发送到同一后端,保持会话粘性。

 

upstream backend {
    ip_hash;
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
    server 192.168.1.103:8080;
}

 

注意:如果需要临时移除某个后端,使用down标记而非直接删除:

 

upstream backend {
    ip_hash;
    server 192.168.1.101:8080;
    server 192.168.1.102:8080 down;  # 临时标记为down
    server 192.168.1.103:8080;
}

 

4.4 最少连接(least_conn)

将请求发送到当前连接数最少的服务器。

 

upstream backend {
    least_conn;
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
    server 192.168.1.103:8080;
}

 

4.5 最少时间(least_time)

Nginx Plus独有功能,综合考虑连接数和响应时间。

 

# Nginx Plus配置
upstream backend {
    least_time header;
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
}

 

4.6 完整upstream配置示例

 

# 完整反向代理配置
upstream tomcat_cluster {
    # 加权最小连接
    least_conn;

    # 后端服务器定义
    server 192.168.1.101:8080 weight=3 max_fails=3 fail_timeout=30s;
    server 192.168.1.102:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 192.168.1.103:8080 backup;  # 备份服务器

    # 连接保持时间
    keepalive 32;
}

# upstream详细参数说明:
# weight=N         加权轮询权重
# max_fails=N      最大失败次数,超过后认为服务器不可用
# fail_timeout=30s 失败超时时间
# backup           标记为备份服务器
# down             标记为永久不可用

 

5. proxy_buffering与缓存配置

5.1 缓冲区配置原理

 

Client <---> Nginx Worker <---> Upstream Server
              |
              +-- proxy_buffer_size: 读取响应头
              +-- proxy_buffers: 读取响应体
              +-- proxy_busy_buffers_size: 忙时缓冲区
              +-- proxy_cache: 缓存存储

 

5.2 基础代理缓冲区配置

 

location / {
    proxy_pass http://backend;

    # 响应头缓冲区大小
    proxy_buffer_size 4k;

    # 响应体缓冲区数量和大小
    proxy_buffers 8 16k;

    # 忙时缓冲区(向客户端发送时使用)
    proxy_busy_buffers_size 32k;

    # 缓冲区超时
    proxy_connect_timeout 60s;
    proxy_read_timeout 60s;
    proxy_send_timeout 60s;
}

 

5.3 高并发代理配置

 

location /api/ {
    proxy_pass http://backend;

    # 更大的缓冲区
    proxy_buffer_size 64k;
    proxy_buffers 16 64k;

    # 启用缓冲
    proxy_buffering on;

    # 磁盘缓存大小
    proxy_buffer_size 64k;
    proxy_buffers 256 16k;

    # 忙时缓冲区
    proxy_busy_buffers_size 128k;

    # 客户端下载限速(0表示不限)
    proxy_download_rate 0;
}

 

5.4 关闭代理缓冲

适用于需要实时推送或长连接场景。

 

location /streaming/ {
    proxy_pass http://backend;

    # 关闭缓冲,直接转发
    proxy_buffering off;
    proxy_cache off;

    # WebSocket支持
    proxy_http_version 1.1;
    proxy_set_header Connection "upgrade";
}

 

5.5 HTTP缓存配置

 

# 定义缓存区
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

# 使用缓存
location / {
    proxy_pass http://backend;
    proxy_cache my_cache;

    # 缓存key
    proxy_cache_key "$scheme$request_method$host$request_uri";

    # 缓存有效期
    proxy_cache_valid 200 60m;
    proxy_cache_valid 404 1m;

    # 缓存状态头
    add_header X-Cache-Status $upstream_cache_status;

    # 缓存绕过条件
    proxy_cache_bypass $cookie_nocache $arg_nocache;
}

 

5.6 缓存状态详解

 

# X-Cache-Status可能的值:
# MISS    - 缓存未命中,需要回源
# HIT     - 缓存命中
# EXPIRED - 缓存已过期
# STALE   - 使用过期缓存(后端不可用时)
# UPDATING- 正在更新缓存
# REVALIDATED - 缓存已验证

 

6. keepalive连接复用

6.1 upstream keepalive

 

upstream backend {
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;

    # 启用keepalive
    keepalive 32;
}

location / {
    proxy_pass http://backend;

    # HTTP 1.1
    proxy_http_version 1.1;

    # 清空Connection头
    proxy_set_header Connection "";
}

 

6.2 客户端keepalive

 

server {
    listen 80;
    server_name example.com;

    # 客户端keepalive超时
    keepalive_timeout 65;

    # 单个keepalive连接最大请求数
    keepalive_requests 1000;

    # 关闭慢启动连接(高并发场景)
    tcp_nopush off;
    tcp_nodelay on;
}

 

6.3 keepalive配置对比

 

# 配置1:面向后端的keepalive
upstream api {
    server 127.0.0.1:8080;
    keepalive 64;
}

# 配置2:面向客户端的keepalive
server {
    keepalive_timeout 120;
    keepalive_requests 10000;
}

 

7. Gzip压缩优化

7.1 Gzip基础配置

 

http {
    gzip on;
    gzip_min_length 1024;
    gzip_comp_level 4;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
    gzip_vary on;
    gzip_proxied any;
    gzip_disable "msie6";
}

 

7.2 Gzip参数详解

 

http {
    # 启用gzip
    gzip on;

    # 最小压缩阈值(小于此大小不压缩)
    gzip_min_length 256;

    # 压缩级别(1-9,4是性价比最优)
    gzip_comp_level 4;

    # 压缩类型
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml
        application/xml+rss
        application/x-javascript
        image/svg+xml;

    # 添加Vary头(代理缓存需要)
    gzip_vary on;

    # 对代理请求启用压缩
    gzip_proxied any;

    # 禁用IE6 gzip(IE6有bug)
    gzip_disable "MSIE [1-6].";
}

 

7.3 Brotli压缩(更优压缩比)

 

# 需要nginx-modules: --with-http_brotli_filter_module

http {
    # Brotli开关
    brotli on;
    brotli_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;
    brotli_comp_level 4;
    brotli_min_length 256;
}

 

7.4 压缩效果对比

 

# 测试gzip压缩效果
$ curl -I -H "Accept-Encoding: gzip" http://example.com/api/data

HTTP/1.1 200 OK
Server: nginx
Content-Encoding: gzip
Vary: Accept-Encoding
Transfer-Encoding: chunked

# 压缩前后对比(JSON API示例)
# 原始大小: 50KB
# Gzip压缩: 12KB (压缩率76%)
# Brotli压缩: 10KB (压缩率80%)

 

8. 静态资源缓存配置

8.1 静态文件缓存策略

 

server {
    listen 80;
    server_name static.example.com;
    root /var/www/static;

    # CSS/JS缓存1年
    location ~* .(css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # 图片缓存1个月
    location ~* .(jpg|jpeg|png|gif|ico|webp|svg)$ {
        expires 30d;
        add_header Cache-Control "public";
        access_log off;
    }

    # 字体缓存1年
    location ~* .(woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public";
        access_log off;
    }

    # HTML不缓存
    location ~* .html$ {
        expires -1;
        add_header Cache-Control "no-cache, no-store";
    }
}

 

8.2 静态资源性能优化

 

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

    # 静态资源服务器配置
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # 读取超时
    client_body_timeout 12;
    client_header_timeout 12;
}

 

8.3 跨域资源共享(CORS)

 

location /assets/ {
    # CORS配置
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
    add_header 'Access-Control-Max-Age' 86400;

    # 预检请求处理
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Max-Age' 86400;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
    }

    expires 30d;
    add_header Cache-Control "public";
}

 

9. SSL/TLS握手优化

9.1 HTTPS基础配置

 

server {
    listen 443 ssl http2;
    server_name example.com;

    # 证书配置
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    # TLS版本控制
    ssl_protocols TLSv1.2 TLSv1.3;

    # 加密套件
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    # 会话缓存
    ssl_session_cache shared10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
}

 

9.2 现代SSL配置

 

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    # 只启用TLS 1.3(最新、最快、最安全)
    ssl_protocols TLSv1.3;

    # 使用现代加密套件
    ssl_ciphers TLS_AES_256_GCM_SHA384ECDHE-RSA-AES256-GCM-SHA384;

    # 禁用服务器端cipher偏好(客户端优先)
    ssl_prefer_server_ciphers off;

    # HSTS
    add_header Strict-Transport-Security "max-age=63072000" always;

    # 证书透明度
    ssl_trusted_certificate /etc/nginx/ssl/chain.pem;
}

 

9.3 SSL性能优化

 

http {
    # 全局SSL缓存
    ssl_session_cache shared50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # OCSP缓存
    ssl_stapling on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    # 证书
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    # 启用0-RTT(TLS 1.3特性,减少握手延迟)
    ssl_early_data on;

    # 连接复用
    keepalive_timeout 100;
}

 

9.4 HTTP/2优化

 

server {
    listen 443 ssl http2;
    server_name example.com;

    # HTTP/2推送(可选,已被HTTP/3和 Early Data取代)
    # http2_push_preload on;

    # 并发流控制
    http2_max_concurrent_streams 128;

    # 动态表大小限制
    http2_recv_buffer_size 256k;
}

 

10. 常用优化参数汇总表

10.1 系统级参数

 

# /etc/sysctl.conf 添加以下内容

# 网络参数
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_tw_reuse = 1

# 文件描述符
fs.file-max = 2097152

# 生效配置
$ sysctl -p

 

10.2 /etc/security/limits.conf

 

# 追加以下内容
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535

# 或者针对nginx用户
nginx soft nofile 65535
nginx hard nofile 65535

 

10.3 完整优化配置模板

 

# /etc/nginx/nginx.conf

user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
worker_priority -10;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    use epoll;
    worker_connections 65535;
    multi_accept on;
    accept_mutex off;  # 现代Nginx不需要
}

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=16k flush=5s;

    # 性能参数
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # 超时设置
    keepalive_timeout 65;
    keepalive_requests 10000;
    client_header_timeout 15;
    client_body_timeout 15;
    send_timeout 15;

    # 缓冲区设置
    client_body_buffer_size 16k;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;
    client_max_body_size 50m;

    # Gzip
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_types text/plain text/css text/xml application/json application/javascript
               text/xml application/xml application/xml+rss image/svg+xml;

    # 缓存
    open_file_cache max=10000 inactive=30s;
    open_file_cache_valid 60s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

    # SSL
    ssl_session_cache shared50m;
    ssl_session_timeout 1d;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;

    # 隐藏版本号
    server_tokens off;

    # 加载其他配置
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

 

11. 配置检查与压测方法

11.1 配置语法检查

 

# 测试配置文件语法
$ nginx -t

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# 查看配置详细信息
$ nginx -T

# 指定配置文件测试
$ nginx -t -c /path/to/nginx.conf

# 显示编译时的配置参数
$ nginx -V

 

11.2 压测工具

 

# 安装wrk
$ dnf install wrk -y

# 基础压测
$ wrk -t12 -c400 -d30s http://127.0.0.1/

# 使用Lua脚本自定义压测
$ wrk -t12 -c400 -d30s -s post.lua http://127.0.0.1/api

# 输出示例
Running 30s test @ http://127.0.0.1/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     5.23ms    2.15ms  45.12ms   78.45%
    Req/Sec    6.38k     523.45   12.45k    68.90%
  22953432 requests in 30.10s, 2.45GB read
Requests/sec: 762534.23
Transfer/sec:    83.45MB

 

11.3 ab压测

 

# 安装
$ dnf install httpd-tools -y

# 基础压测
$ ab -n 100000 -c 1000 http://127.0.0.1/

# POST请求压测
$ ab -n 10000 -c 100 -p data.json -T application/json http://127.0.0.1/api

 

11.4 压测脚本

 

#!/bin/bash
# script: nginx_load_test.sh
# 用途:自动化Nginx性能压测

TARGET_URL="${1//127.0.0.1/}"
REPORT_FILE="/tmp/nginx_load_test_$(date +%Y%m%d_%H%M%S).txt"

echo"=== Nginx 性能压测 ==="
echo"目标URL: ${TARGET_URL}"
echo"测试时间: $(date)"
echo""

# 1. 并发100,持续30秒
echo"【1】低并发测试 (100并发, 30秒)..."
wrk -t4 -c100 -d30s "${TARGET_URL}" 2>&1 | tee -a "${REPORT_FILE}"
echo""

# 2. 并发500,持续30秒
echo"【2】中并发测试 (500并发, 30秒)..."
wrk -t8 -c500 -d30s "${TARGET_URL}" 2>&1 | tee -a "${REPORT_FILE}"
echo""

# 3. 并发1000,持续60秒
echo"【3】高并发测试 (1000并发, 60秒)..."
wrk -t16 -c1000 -d60s "${TARGET_URL}" 2>&1 | tee -a "${REPORT_FILE}"
echo""

# 4. 慢连接测试
echo"【4】慢连接测试 (100并发, 持续连接)..."
wrk -t4 -c100 -d30s --latency "${TARGET_URL}" 2>&1 | tee -a "${REPORT_FILE}"
echo""

echo"测试完成,报告保存到: ${REPORT_FILE}"

 

12. 常见配置错误排障

12.1 常见错误及解决方案

错误1:403 Forbidden

 

# 排查步骤
$ ls -la /var/www/html/index.html
-rw-r--r-- 1 nginx nginx 4096 Apr  3 10:00 /var/www/html/index.html
# 文件存在,但nginx用户没有读取权限

# 解决方案
chown nginx:nginx /var/www/html/index.html
chmod 644 /var/www/html

# 检查SELinux
ls -Z /var/www/html/index.html
chcon -t httpd_sys_content_t /var/www/html/index.html

 

错误2:502 Bad Gateway

 

# 排查步骤
# 1. 检查upstream服务是否运行
curl -v http://127.0.0.1:8080/health

# 2. 检查nginx upstream配置
$ tail -50 /var/log/nginx/error.log | grep "upstream"

# 3. 检查连接超时
proxy_connect_timeout 60s;
proxy_read_timeout 60s;

 

错误3:504 Gateway Timeout

 

# 调整超时时间
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;

# 或检查后端性能
upstream backend {
    least_conn;
    server 127.0.0.1:8080 weight=3;
}

 

12.2 排障脚本

 

#!/bin/bash
# script: nginx_troubleshoot.sh
# 用途:Nginx常见问题排查

echo"=== Nginx 故障排查 ==="
echo""

# 1. 检查进程状态
echo"【1】Nginx进程状态:"
systemctl status nginx | head -10
echo""

# 2. 检查配置文件语法
echo"【2】配置文件语法检查:"
nginx -t 2>&1
echo""

# 3. 检查端口占用
echo"【3】端口占用情况:"
ss -tlnp | grep -E ':80|:443'
echo""

# 4. 检查错误日志
echo"【4】最近错误日志:"
tail -20 /var/log/nginx/error.log
echo""

# 5. 检查upstream连通性
echo"【5】后端服务检查:"
curl -s -o /dev/null -w "HTTP %{http_code}" http://127.0.0.1:8080/health || echo"Backend unreachable"
echo""

# 6. 检查缓存目录权限
echo"【6】缓存目录状态:"
ls -la /var/cache/nginx/ 2>/dev/null || echo"No cache dir"
echo""

# 7. 检查磁盘空间
echo"【7】磁盘空间检查:"
df -h /var/log/nginx
echo""

 

12.3 监控脚本

 

#!/bin/bash
# script: nginx_monitor.sh
# 用途:Nginx状态监控

ALERT_EMAIL="ops@example.com"

# 检查Nginx是否运行
check_nginx() {
    if ! systemctl is-active nginx &>/dev/null; then
        echo"CRITICAL: Nginx is not running!"
        return 1
    fi

    # 检查worker进程数
    worker_count=$(ps aux | grep "nginx: worker" | grep -v grep | wc -l)
    if [ "$worker_count" -eq 0 ]; then
        echo"CRITICAL: No worker processes!"
        return 1
    fi

    echo"OK: Nginx running with $worker_count workers"
    return 0
}

# 检查连接状态
check_connections() {
    active=$(curl -s http://127.0.0.1/nginx_status | grep "Active" | awk '{print $2}')
    reading=$(curl -s http://127.0.0.1/nginx_status | grep "Reading" | awk '{print $2}')
    writing=$(curl -s http://127.0.0.1/nginx_status | grep "Writing" | awk '{print $2}')
    waiting=$(curl -s http://127.0.0.1/nginx_status | grep "Waiting" | awk '{print $2}')

    echo"Connections: active=$active reading=$reading writing=$writing waiting=$waiting"
}

# 启用stub_status需要在nginx.conf中添加
# location /nginx_status {
#     stub_status on;
#     access_log off;
#     allow 127.0.0.1;
#     deny all;
# }

check_nginx
check_connections

 

总结

核心配置要点

配置项 推荐值 说明
worker_processes auto 自动匹配CPU核心数
worker_connections 65535 最大并发连接数
worker_cpu_affinity auto CPU亲和性绑定
multi_accept on 一次accept多个连接
sendfile on 高效文件传输
tcp_nopush on 配合sendfile优化
tcp_nodelay on 禁用Nagle算法
keepalive_timeout 65 客户端连接保持时间
gzip on 启用压缩
ssl_protocols TLSv1.2 TLSv1.3 禁用旧版本SSL

性能优化检查清单

 

□ worker_processes设置为auto
□ worker_connections足够高(65535)
□ 启用了epoll
□ multi_accept开启
□ sendfile开启
□ keepalive配置正确
□ Gzip压缩启用
□ 静态资源缓存配置
□ SSL使用TLS 1.2/1.3
□ upstream使用keepalive
□ 文件描述符限制足够高
□ 内核参数已优化
□ 监控和压测完成

 

命令速查

场景 命令
检查配置 nginx -t
重载配置 nginx -s reload
优雅重启 kill -HUP $(cat /var/run/nginx.pid)
热升级 nginx -v  + make upgrade
查看状态 nginx -V
设置worker优先级 worker_priority -10
查看连接状态 curl http://127.0.0.1/nginx_status

参考信息

版本信息

Nginx:1.26.x(主线版本)或1.24.x(稳定版本)

OpenSSL:3.2.x

操作系统:Rocky Linux 9.4

内核版本:6.8.5

性能基准参考

单worker处理静态文件:50,000+ req/s

单worker处理反向代理:10,000+ req/s

TLS握手延迟(TLS 1.3):~50ms

Gzip压缩开销:~5% CPU

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分