背景與目的
Nginx是現(xiàn)代互聯(lián)網(wǎng)架構(gòu)中最常用的Web服務(wù)器和反向代理軟件。很多運維工程師使用Nginx多年,卻對其核心架構(gòu)一知半解,配置優(yōu)化時只會機(jī)械地調(diào)整幾個參數(shù)。本文從Nginx進(jìn)程模型出發(fā),深入講解worker進(jìn)程的工作機(jī)制,幫助你理解每個配置參數(shù)背后的原理,實現(xiàn)真正有效的優(yōu)化。
前置知識:本文假設(shè)你已經(jīng)具備Linux基礎(chǔ)操作能力,了解Web服務(wù)器的基本概念,有過實際部署和維護(hù)Nginx的經(jīng)驗。
環(huán)境說明:本文基于Nginx 1.26.x(主線版本),操作系統(tǒng)Rocky Linux 9.4,OpenSSL 3.2.x。
1. Nginx進(jìn)程模型解析
1.1 進(jìn)程架構(gòu)概述
Nginx采用多進(jìn)程架構(gòu),而非多線程架構(gòu)。這是刻意設(shè)計的選擇,有以下優(yōu)勢:
master進(jìn)程:主進(jìn)程,負(fù)責(zé)以下工作:
讀取和驗證配置文件
管理worker進(jìn)程(啟動、停止、重啟)
處理熱部署(熱升級)
worker進(jìn)程:工作進(jìn)程,實際處理請求:
接收客戶端連接
處理HTTP請求
與后端服務(wù)器通信(反向代理)
緩存處理
日志寫入
cache loader和cache manager:僅在啟用緩存時存在
cache loader:加載緩存元數(shù)據(jù)到內(nèi)存
cache manager:管理緩存過期和清理
# 查看Nginx進(jìn)程結(jié)構(gòu) $ 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 # 進(jìn)程關(guān)系圖 # # [master process] # | # +-----------+-----------+ # | | | # [worker] [worker] [worker] ... # | | | # (CPU) (CPU) (CPU) # # 所有worker進(jìn)程共享同一個監(jiān)聽端口
1.2 為什么選擇多進(jìn)程而非多線程
多線程的問題:
共享地址空間,線程安全問題復(fù)雜
一個線程崩潰可能影響整個進(jìn)程
內(nèi)存同步開銷大
調(diào)試?yán)щy
多進(jìn)程的優(yōu)勢:
worker進(jìn)程完全獨立,互不影響
一個worker崩潰不會影響其他worker
每個worker可以獨立運行在多核CPU上
簡化內(nèi)存管理(進(jìn)程間不共享內(nèi)存)
驚群問題(Thundering Herd):
舊版Nginx存在驚群問題:一個連接到來時所有worker被喚醒,但只有1個能搶到
Nginx 1.11.3+通過socket sharding解決此問題
現(xiàn)代Nginx使用SO_REUSEPORT,允許內(nèi)核層面分發(fā)連接
1.3 連接處理模型
Nginx使用事件驅(qū)動架構(gòu),基于I/O多路復(fù)用(Linux上是epoll,F(xiàn)reeBSD是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 ... # 查看系統(tǒng)支持的事件模型 $ 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進(jìn)程數(shù)量。
# 自動檢測CPU核心數(shù)(推薦配置) worker_processes auto; # 固定值 worker_processes 4; # 查看CPU核心數(shù) $ nproc 8 # 查看CPU詳細(xì)信息 $ lscpu
最佳實踐:
生產(chǎn)環(huán)境建議使用auto,讓Nginx自動匹配CPU核心數(shù)
如果有多個Nginx實例在不同端口,不要讓總數(shù)超過CPU核心數(shù)
綁定到特定CPU核心:worker_cpu_affinity
2.2 worker_cpu_affinity綁定
將worker進(jìn)程綁定到特定CPU核心,避免進(jìn)程切換開銷。
# 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;
驗證綁定效果:
# 查看進(jìn)程CPU親和性 $ ps -eo pid,psr,comm | grep nginx 12346 0 nginx 12347 1 nginx 12348 2 nginx 12349 3 nginx # PSR列表示當(dāng)前運行的CPU核心
2.3 worker_priority調(diào)整
# 設(shè)置worker進(jìn)程優(yōu)先級(-20到20,越低優(yōu)先級越高) # 默認(rèn)-15到15,設(shè)置為負(fù)數(shù)獲得更高優(yōu)先級 worker_priority -10;
2.4 worker_rlimit_nofile
設(shè)置單個worker進(jìn)程能打開的最大文件描述符數(shù)量。
# 系統(tǒng)級限制 # /etc/security/limits.conf # * soft nofile 65535 # * hard nofile 65535 worker_rlimit_nofile 65535;
文件描述符消耗來源:
客戶端連接(每個連接1個fd)
upstream連接池
打開的緩存文件
打開的日志文件
# 查看系統(tǒng)級文件描述符限制 $ cat /proc/sys/fs/file-max # 查看當(dāng)前使用量 $ cat /proc/sys/fs/file-nr 1024 0 65535 # 已分配 分配中 最大值 # 查看單個進(jìn)程限制 $ cat /proc/12346/limits
3. worker_connections與并發(fā)控制
3.1 worker_connections詳解
每個worker進(jìn)程能處理的最大并發(fā)連接數(shù)。
events {
# 默認(rèn)512,生產(chǎn)環(huán)境通常設(shè)置更高
worker_connections 1024;
# 使用epoll(Linux默認(rèn))
use epoll;
# 啟用異步I/O
# aio on;
# 多路復(fù)用accept(減少驚群)
multi_accept on;
}
理論最大并發(fā)計算:
# 最大并發(fā) = worker_processes * worker_connections # 但實際上還要考慮: # 1. 每個連接占用文件描述符 # 2. 瀏覽器通常每個域名2-8個并發(fā)連接 # 3. 反向代理時upstream連接也要占用fd # 例如: # worker_processes = 4 # worker_connections = 1024 # 最大并發(fā) = 4 * 1024 = 4096 # 但反向代理時需要預(yù)留一半給upstream: # 實際可處理客戶端連接 = 2048
3.2 最大連接數(shù)計算
# nginx.conf worker_processes auto; worker_connections 4096; # 計算公式 # 最大TCP連接數(shù) = worker_processes * worker_connections # 最大并發(fā)客戶端 = 最大TCP連接數(shù) / 2(HTTP Keep-Alive)
3.3 實際配置示例
# 通用Web服務(wù)器配置
worker_processes auto;
worker_connections 4096;
worker_rlimit_nofile 65535;
events {
use epoll;
multi_accept on;
worker_connections 4096;
}
# 高并發(fā)靜態(tài)資源服務(wù)器
worker_processes auto;
worker_connections 16384;
worker_rlimit_nofile 262144;
events {
use epoll;
multi_accept on;
worker_connections 16384;
}
# 反向代理服務(wù)器(需要預(yù)留upstream連接)
worker_processes auto;
worker_connections 8192;
worker_rlimit_nofile 32768;
events {
use epoll;
multi_accept on;
}
4. upstream負(fù)載均衡策略
4.1 輪詢(round_robin)
默認(rèn)策略,按順序依次分發(fā)請求。
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 加權(quán)輪詢(weight)
根據(jù)權(quán)重比例分發(fā)請求,適合后端性能不均的場景。
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%
}
# 或者后端性能強(qiáng)的多分配
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的請求始終發(fā)送到同一后端,保持會話粘性。
upstream backend {
ip_hash;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.103:8080;
}
注意:如果需要臨時移除某個后端,使用down標(biāo)記而非直接刪除:
upstream backend {
ip_hash;
server 192.168.1.101:8080;
server 192.168.1.102:8080 down; # 臨時標(biāo)記為down
server 192.168.1.103:8080;
}
4.4 最少連接(least_conn)
將請求發(fā)送到當(dāng)前連接數(shù)最少的服務(wù)器。
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獨有功能,綜合考慮連接數(shù)和響應(yīng)時間。
# 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 {
# 加權(quán)最小連接
least_conn;
# 后端服務(wù)器定義
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; # 備份服務(wù)器
# 連接保持時間
keepalive 32;
}
# upstream詳細(xì)參數(shù)說明:
# weight=N 加權(quán)輪詢權(quán)重
# max_fails=N 最大失敗次數(shù),超過后認(rèn)為服務(wù)器不可用
# fail_timeout=30s 失敗超時時間
# backup 標(biāo)記為備份服務(wù)器
# down 標(biāo)記為永久不可用
5. proxy_buffering與緩存配置
5.1 緩沖區(qū)配置原理
Client <---> Nginx Worker <---> Upstream Server
|
+-- proxy_buffer_size: 讀取響應(yīng)頭
+-- proxy_buffers: 讀取響應(yīng)體
+-- proxy_busy_buffers_size: 忙時緩沖區(qū)
+-- proxy_cache: 緩存存儲
5.2 基礎(chǔ)代理緩沖區(qū)配置
location / {
proxy_pass http://backend;
# 響應(yīng)頭緩沖區(qū)大小
proxy_buffer_size 4k;
# 響應(yīng)體緩沖區(qū)數(shù)量和大小
proxy_buffers 8 16k;
# 忙時緩沖區(qū)(向客戶端發(fā)送時使用)
proxy_busy_buffers_size 32k;
# 緩沖區(qū)超時
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
5.3 高并發(fā)代理配置
location /api/ {
proxy_pass http://backend;
# 更大的緩沖區(qū)
proxy_buffer_size 64k;
proxy_buffers 16 64k;
# 啟用緩沖
proxy_buffering on;
# 磁盤緩存大小
proxy_buffer_size 64k;
proxy_buffers 256 16k;
# 忙時緩沖區(qū)
proxy_busy_buffers_size 128k;
# 客戶端下載限速(0表示不限)
proxy_download_rate 0;
}
5.4 關(guān)閉代理緩沖
適用于需要實時推送或長連接場景。
location /streaming/ {
proxy_pass http://backend;
# 關(guān)閉緩沖,直接轉(zhuǎn)發(fā)
proxy_buffering off;
proxy_cache off;
# WebSocket支持
proxy_http_version 1.1;
proxy_set_header Connection "upgrade";
}
5.5 HTTP緩存配置
# 定義緩存區(qū)
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;
# 緩存狀態(tài)頭
add_header X-Cache-Status $upstream_cache_status;
# 緩存繞過條件
proxy_cache_bypass $cookie_nocache $arg_nocache;
}
5.6 緩存狀態(tài)詳解
# X-Cache-Status可能的值: # MISS - 緩存未命中,需要回源 # HIT - 緩存命中 # EXPIRED - 緩存已過期 # STALE - 使用過期緩存(后端不可用時) # UPDATING- 正在更新緩存 # REVALIDATED - 緩存已驗證
6. keepalive連接復(fù)用
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連接最大請求數(shù)
keepalive_requests 1000;
# 關(guān)閉慢啟動連接(高并發(fā)場景)
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壓縮優(yōu)化
7.1 Gzip基礎(chǔ)配置
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參數(shù)詳解
http {
# 啟用gzip
gzip on;
# 最小壓縮閾值(小于此大小不壓縮)
gzip_min_length 256;
# 壓縮級別(1-9,4是性價比最優(yōu))
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壓縮(更優(yōu)壓縮比)
# 需要nginx-modules: --with-http_brotli_filter_module
http {
# Brotli開關(guān)
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. 靜態(tài)資源緩存配置
8.1 靜態(tài)文件緩存策略
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 靜態(tài)資源性能優(yōu)化
http {
# 打開文件緩存
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# 靜態(tài)資源服務(wù)器配置
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;
# 預(yù)檢請求處理
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握手優(yōu)化
9.1 HTTPS基礎(chǔ)配置
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 現(xiàn)代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;
# 使用現(xiàn)代加密套件
ssl_ciphers TLS_AES_256_GCM_SHA384ECDHE-RSA-AES256-GCM-SHA384;
# 禁用服務(wù)器端cipher偏好(客戶端優(yōu)先)
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性能優(yōu)化
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;
# 連接復(fù)用
keepalive_timeout 100;
}
9.4 HTTP/2優(yōu)化
server {
listen 443 ssl http2;
server_name example.com;
# HTTP/2推送(可選,已被HTTP/3和 Early Data取代)
# http2_push_preload on;
# 并發(fā)流控制
http2_max_concurrent_streams 128;
# 動態(tài)表大小限制
http2_recv_buffer_size 256k;
}
10. 常用優(yōu)化參數(shù)匯總表
10.1 系統(tǒng)級參數(shù)
# /etc/sysctl.conf 添加以下內(nèi)容 # 網(wǎng)絡(luò)參數(shù) 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
# 追加以下內(nèi)容 * soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535 # 或者針對nginx用戶 nginx soft nofile 65535 nginx hard nofile 65535
10.3 完整優(yōu)化配置模板
# /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; # 現(xiàn)代Nginx不需要
}
http {
# 基礎(chǔ)設(shè)置
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;
# 性能參數(shù)
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 超時設(shè)置
keepalive_timeout 65;
keepalive_requests 10000;
client_header_timeout 15;
client_body_timeout 15;
send_timeout 15;
# 緩沖區(qū)設(shè)置
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.conftestis successful # 查看配置詳細(xì)信息 $ nginx -T # 指定配置文件測試 $ nginx -t -c /path/to/nginx.conf # 顯示編譯時的配置參數(shù) $ nginx -V
11.2 壓測工具
# 安裝wrk $ dnf install wrk -y # 基礎(chǔ)壓測 $ wrk -t12 -c400 -d30s http://127.0.0.1/ # 使用Lua腳本自定義壓測 $ wrk -t12 -c400 -d30s -s post.lua http://127.0.0.1/api # 輸出示例 Running 30stest@ 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 requestsin30.10s, 2.45GBread Requests/sec: 762534.23 Transfer/sec: 83.45MB
11.3 ab壓測
# 安裝 $ dnf install httpd-tools -y # 基礎(chǔ)壓測 $ 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"目標(biāo)URL:${TARGET_URL}"
echo"測試時間:$(date)"
echo""
# 1. 并發(fā)100,持續(xù)30秒
echo"【1】低并發(fā)測試 (100并發(fā), 30秒)..."
wrk -t4 -c100 -d30s"${TARGET_URL}"2>&1 | tee -a"${REPORT_FILE}"
echo""
# 2. 并發(fā)500,持續(xù)30秒
echo"【2】中并發(fā)測試 (500并發(fā), 30秒)..."
wrk -t8 -c500 -d30s"${TARGET_URL}"2>&1 | tee -a"${REPORT_FILE}"
echo""
# 3. 并發(fā)1000,持續(xù)60秒
echo"【3】高并發(fā)測試 (1000并發(fā), 60秒)..."
wrk -t16 -c1000 -d60s"${TARGET_URL}"2>&1 | tee -a"${REPORT_FILE}"
echo""
# 4. 慢連接測試
echo"【4】慢連接測試 (100并發(fā), 持續(xù)連接)..."
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用戶沒有讀取權(quán)限 # 解決方案 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服務(wù)是否運行 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
# 調(diào)整超時時間
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. 檢查進(jìn)程狀態(tài)
echo"【1】Nginx進(jìn)程狀態(tài):"
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】后端服務(wù)檢查:"
curl -s -o /dev/null -w"HTTP %{http_code}"http://127.0.0.1:8080/health ||echo"Backend unreachable"
echo""
# 6. 檢查緩存目錄權(quán)限
echo"【6】緩存目錄狀態(tài):"
ls -la /var/cache/nginx/ 2>/dev/null ||echo"No cache dir"
echo""
# 7. 檢查磁盤空間
echo"【7】磁盤空間檢查:"
df -h /var/log/nginx
echo""
12.3 監(jiān)控腳本
#!/bin/bash
# script: nginx_monitor.sh
# 用途:Nginx狀態(tài)監(jiān)控
ALERT_EMAIL="ops@example.com"
# 檢查Nginx是否運行
check_nginx() {
if! systemctl is-active nginx &>/dev/null;then
echo"CRITICAL: Nginx is not running!"
return1
fi
# 檢查worker進(jìn)程數(shù)
worker_count=$(ps aux | grep"nginx: worker"| grep -v grep | wc -l)
if["$worker_count"-eq 0 ];then
echo"CRITICAL: No worker processes!"
return1
fi
echo"OK: Nginx running with$worker_countworkers"
return0
}
# 檢查連接狀態(tài)
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=$activereading=$readingwriting=$writingwaiting=$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
總結(jié)
核心配置要點
| 配置項 | 推薦值 | 說明 |
|---|---|---|
| worker_processes | auto | 自動匹配CPU核心數(shù) |
| worker_connections | 65535 | 最大并發(fā)連接數(shù) |
| worker_cpu_affinity | auto | CPU親和性綁定 |
| multi_accept | on | 一次accept多個連接 |
| sendfile | on | 高效文件傳輸 |
| tcp_nopush | on | 配合sendfile優(yōu)化 |
| tcp_nodelay | on | 禁用Nagle算法 |
| keepalive_timeout | 65 | 客戶端連接保持時間 |
| gzip | on | 啟用壓縮 |
| ssl_protocols | TLSv1.2 TLSv1.3 | 禁用舊版本SSL |
性能優(yōu)化檢查清單
□ worker_processes設(shè)置為auto □ worker_connections足夠高(65535) □ 啟用了epoll □ multi_accept開啟 □ sendfile開啟 □ keepalive配置正確 □ Gzip壓縮啟用 □ 靜態(tài)資源緩存配置 □ SSL使用TLS 1.2/1.3 □ upstream使用keepalive □ 文件描述符限制足夠高 □ 內(nèi)核參數(shù)已優(yōu)化 □ 監(jiān)控和壓測完成
命令速查
| 場景 | 命令 |
|---|---|
| 檢查配置 | nginx -t |
| 重載配置 | nginx -s reload |
| 優(yōu)雅重啟 | kill -HUP $(cat /var/run/nginx.pid) |
| 熱升級 | nginx -v +make upgrade |
| 查看狀態(tài) | nginx -V |
| 設(shè)置worker優(yōu)先級 | worker_priority -10 |
| 查看連接狀態(tài) | curl http://127.0.0.1/nginx_status |
參考信息
版本信息:
Nginx:1.26.x(主線版本)或1.24.x(穩(wěn)定版本)
OpenSSL:3.2.x
操作系統(tǒng):Rocky Linux 9.4
內(nèi)核版本:6.8.5
性能基準(zhǔn)參考:
單worker處理靜態(tài)文件:50,000+ req/s
單worker處理反向代理:10,000+ req/s
TLS握手延遲(TLS 1.3):~50ms
Gzip壓縮開銷:~5% CPU
-
Web
+關(guān)注
關(guān)注
2文章
1309瀏覽量
74890 -
服務(wù)器
+關(guān)注
關(guān)注
14文章
10328瀏覽量
91686 -
nginx
+關(guān)注
關(guān)注
0文章
192瀏覽量
13186
原文標(biāo)題:Nginx 配置優(yōu)化實戰(zhàn):從吃透 worker 進(jìn)程到性能調(diào)優(yōu)
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
鴻蒙原生應(yīng)用開發(fā)-ArkTS語言基礎(chǔ)類庫多線程TaskPool和Worker的對比(二)
nginx重啟命令linux步驟是什么?
nginx重啟命令linux步驟是什么?
TaskPool和Worker的對比分析
Linux運維Nginx軟件優(yōu)化之安全優(yōu)化
Linux運維Nginx軟件優(yōu)化之Nginx性能優(yōu)化
Linux下Nginx的常用命令------啟動、停止、重啟
分享nginx 502的解決方法
normal worker_pool詳細(xì)的創(chuàng)建過程代碼分析
Nginx 如何實現(xiàn)高性能低消耗
使用lsof實現(xiàn)對linux文件的誤刪除恢復(fù)練習(xí)
Nginx性能優(yōu)化終極指南
Nginx中Master與Worker進(jìn)程的工作機(jī)制
評論