0%

Nginx 配置最佳实践:从入门到精通

Nginx 配置最佳实践:从入门到精通

本文全面讲解 Nginx 的配置语法、常用场景、性能优化和安全加固,帮助运维和开发人员构建高性能、高可用的 Web 服务。

一、Nginx 基础架构

1.1 Nginx 工作原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
graph TB
A[客户端请求] --> B[Master 进程]
B --> C[Worker 进程 1]
B --> D[Worker 进程 2]
B --> E[Worker 进程 N]
C --> F[处理请求]
D --> F
E --> F
F --> G[返回响应]

style B fill:#ff6b6b
style C fill:#4ecdc4
style D fill:#4ecdc4
style E fill:#4ecdc4

核心概念:

  • Master 进程:管理 Worker 进程,处理配置加载、日志打开等
  • Worker 进程:处理实际请求,多进程模型
  • 事件驱动:非阻塞 I/O,高并发性能
  • 连接复用:Keepalive 减少连接开销

1.2 安装 Nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Ubuntu/Debian
apt update
apt install nginx -y

# CentOS/RHEL
yum install epel-release -y
yum install nginx -y

# 从源码编译
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_ssl_module \
--with-http_stub_status_module \
--with-http_gzip_static_module
make && make install

# 验证安装
nginx -v
nginx -V # 查看详细配置

# 管理 Nginx
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
systemctl reload nginx # 平滑重载
systemctl status nginx

# 测试配置
nginx -t
nginx -T # 显示完整配置

1.3 目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Nginx 目录结构
/etc/nginx/
├── nginx.conf # 主配置文件
├── mime.types # MIME 类型配置
├── conf.d/ # 额外配置文件
│ ├── default.conf
│ └── example.com.conf
├── sites-available/ # 可用站点配置(Debian)
├── sites-enabled/ # 启用站点配置(Debian)
├── modules-available/ # 可用模块
├── modules-enabled/ # 启用模块
├── ssl/ # SSL 证书
├── logs/ # 日志目录
│ ├── access.log
│ └── error.log
└── conf/ # 其他配置
├── fastcgi.conf
├── koi-utf
└── win-utf

# 网站目录
/var/www/
└── html/
└── index.html

# 日志目录(自定义)
/var/log/nginx/
├── access.log
└── error.log

二、配置文件详解

2.1 nginx.conf 结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 主配置文件结构
user nginx; # 运行用户
worker_processes auto; # Worker 进程数
worker_rlimit_nofile 65535; # 文件描述符限制

error_log /var/log/nginx/error.log warn; # 错误日志
pid /var/run/nginx.pid; # PID 文件

events {
worker_connections 10240; # 每个 Worker 的最大连接数
use epoll; # 使用 epoll 模型(Linux)
multi_accept on; # 一次接受多个连接
}

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"';

access_log /var/log/nginx/access.log main;

# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;

# Gzip 压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json
application/javascript application/xml;

# 包含其他配置
include /etc/nginx/conf.d/*.conf;
}

2.2 核心指令详解

worker_processes

1
2
3
4
5
6
7
8
# 设置 Worker 进程数
worker_processes auto; # 自动(推荐,等于 CPU 核数)
worker_processes 4; # 固定数量
worker_processes 1; # 单进程(调试用)

# 绑定 CPU(提高性能)
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;

worker_connections

1
2
3
4
5
6
7
events {
# 每个 Worker 的最大连接数
worker_connections 10240;

# 最大客户端连接数 = worker_processes × worker_connections
# 例如:4 × 10240 = 40960
}

keepalive_timeout

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
http {
# Keepalive 超时时间
keepalive_timeout 65;

# Keepalive 请求数上限
keepalive_requests 100;

# 与上游服务器的 Keepalive
upstream backend {
server 127.0.0.1:8080;
keepalive 32; # 保持 32 个空闲连接
}

server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
}

三、常用场景配置

3.1 静态文件服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
server {
listen 80;
server_name example.com www.example.com;

root /var/www/example.com;
index index.html index.htm;

# 访问日志
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;

# 静态文件
location / {
try_files $uri $uri/ =404;
}

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

# CSS/JS 缓存
location ~* \.(css|js)$ {
expires 7d;
add_header Cache-Control "public";
access_log off;
}

# 字体文件
location ~* \.(woff|woff2|ttf|eot|otf)$ {
expires 30d;
add_header Cache-Control "public";
access_log off;
}

# 禁止访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}

# 禁止访问备份文件
location ~ ~$ {
deny all;
access_log off;
log_not_found off;
}
}

3.2 反向代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
server {
listen 80;
server_name api.example.com;

location / {
# 代理到后端服务
proxy_pass http://127.0.0.1:8080;

# 传递客户端信息
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 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# 缓冲区
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;

# 临时文件
proxy_temp_file_write_size 64k;
}

# WebSocket 支持
location /ws/ {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
}

3.3 负载均衡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 上游服务器组
upstream backend {
# 轮询(默认)
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;

# 权重
# server 192.168.1.10:8080 weight=3;
# server 192.168.1.11:8080 weight=2;
# server 192.168.1.12:8080 weight=1;

# IP Hash(会话保持)
# ip_hash;

# 最少连接
# least_conn;

# 备用服务器
# server 192.168.1.13:8080 backup;

# 故障服务器
# server 192.168.1.14:8080 down;

# 健康检查参数
# server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;

# Keepalive 连接
keepalive 32;
}

server {
listen 80;
server_name app.example.com;

location / {
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_connect_timeout 10s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;

# 重试
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3;
}
}

3.4 HTTPS 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
server {
listen 443 ssl http2;
server_name example.com www.example.com;

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

# SSL 优化
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

# 现代 SSL 配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

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

root /var/www/example.com;
index index.html;

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

# HTTP 重定向到 HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}

3.5 动静分离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
upstream backend {
server 127.0.0.1:8080;
keepalive 32;
}

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

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

# 动态请求
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection "";
}

# API 接口
location /api/ {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

四、性能优化

4.1 基础优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# nginx.conf
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;

events {
worker_connections 10240;
use epoll;
multi_accept on;
}

http {
# 基础优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;

# Keepalive
keepalive_timeout 65;
keepalive_requests 100;

# 缓冲区
client_body_buffer_size 10M;
client_max_body_size 10M;

# 超时
client_body_timeout 12;
client_header_timeout 12;
keepalive_timeout 15;
send_timeout 10;

# Gzip 压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
font/woff
font/woff2
text/css
text/javascript
text/plain
text/xml;
}

4.2 缓存优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 代理缓存配置
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:100m
max_size=10g inactive=60m use_temp_path=off;

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend;

# 启用缓存
proxy_cache my_cache;

# 缓存键
proxy_cache_key $scheme$request_method$host$request_uri;

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

# 缓存条件
proxy_cache_methods GET HEAD;

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

# 绕过缓存
proxy_cache_bypass $http_pragma $http_authorization;
proxy_no_cache $http_pragma $http_authorization;
}

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

4.3 连接优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
http {
# 打开文件缓存
open_file_cache max=100000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

# 重置超时连接
reset_timedout_connection on;

# 服务器名称哈希
server_names_hash_bucket_size 128;
server_names_hash_max_size 4096;

# 类型哈希
types_hash_max_size 2048;
types_hash_bucket_size 64;

# 限制请求
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
listen 80;
server_name example.com;

# 限制请求频率
location / {
limit_req zone=one burst=20 nodelay;
limit_conn addr 10;

proxy_pass http://backend;
}

# API 限流
location /api/ {
limit_req zone=one burst=5 nodelay;
limit_conn addr 5;

proxy_pass http://backend;
}
}
}

4.4 FastCGI 优化(PHP)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.php index.html;

location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;

# FastCGI 缓存
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2
keys_zone=php_cache:100m max_size=1g
inactive=60m;

fastcgi_cache php_cache;
fastcgi_cache_key $request_method$host$fastcgi_script_name$query_string;
fastcgi_cache_valid 200 30m;
fastcgi_cache_valid 404 1m;
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;

# FastCGI 参数
fastcgi_buffer_size 128k;
fastcgi_buffers 256 16k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;

# 超时
fastcgi_connect_timeout 60s;
fastcgi_send_timeout 180s;
fastcgi_read_timeout 180s;
}
}

五、安全加固

5.1 基础安全配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
server {
listen 80;
server_name example.com;

# 隐藏 Nginx 版本
server_tokens off;

# 安全头
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 Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

# 禁止访问敏感文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}

location ~ ~$ {
deny all;
access_log off;
log_not_found off;
}

location ~* \.(git|svn|htaccess|htpasswd|ini|log|sh|sql|conf|bak|swp)$ {
deny all;
access_log off;
log_not_found off;
}

# 禁止访问备份文件
location ~* \.(bak|backup|old|orig|save|tmp|temp)$ {
deny all;
access_log off;
log_not_found off;
}

# 限制请求方法
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$) {
return 405;
}

# 限制请求体大小
client_max_body_size 10M;

# 限制请求头大小
large_client_header_buffers 4 16k;
}

5.2 DDoS 防护

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
http {
# 限制连接数
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn_zone $server_name zone=server:10m;

# 限制请求频率
limit_req_zone $binary_remote_addr zone=req:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;

# 限制请求体
client_body_buffer_size 10M;
client_max_body_size 10M;

# 超时设置
client_body_timeout 10s;
client_header_timeout 10s;
keepalive_timeout 15s;
send_timeout 10s;

server {
listen 80;
server_name example.com;

# 应用限制
location / {
limit_conn addr 10;
limit_conn server 1000;
limit_req zone=req burst=20 nodelay;

proxy_pass http://backend;
}

# API 严格限制
location /api/ {
limit_conn addr 5;
limit_req zone=api burst=5 nodelay;

proxy_pass http://backend;
}

# 登录接口更严格
location /login {
limit_req zone=api burst=3 nodelay;

proxy_pass http://backend;
}

# 静态文件宽松限制
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
limit_conn addr 20;
limit_req zone=req burst=50;

expires 30d;
access_log off;
}
}
}

# 自定义错误页面
http {
limit_req_status 429;
limit_conn_status 429;

server {
error_page 429 /429.html;
location = /429.html {
root /var/www/error_pages;
internal;
}
}
}

5.3 SSL/TLS 安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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;

# 协议
ssl_protocols TLSv1.2 TLSv1.3;

# 加密套件
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# 会话
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

# OCSP
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

# 安全头
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
}

5.4 访问控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
server {
listen 80;
server_name example.com;

# IP 白名单
location /admin/ {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;

proxy_pass http://backend;
}

# IP 黑名单
# 在 http 块中
# geo $block_ip {
# default 0;
# 192.168.1.100 1;
# 10.0.0.50 1;
# }

# server {
# if ($block_ip) {
# return 403;
# }
# }

# 基本认证
location /private/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;

proxy_pass http://backend;
}

# 基于 User-Agent 的限制
if ($http_user_agent ~* (curl|wget|scrapy|python-requests)) {
return 403;
}

# 基于 Referer 的限制
location ~* \.(jpg|jpeg|png|gif)$ {
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
}
}
}

# 生成 .htpasswd 文件
# htpasswd -c /etc/nginx/.htpasswd username

六、监控与日志

6.1 日志配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
http {
# 自定义日志格式
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"';

log_format json escape=json '{'
'"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status": $status,'
'"body_bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"upstream_response_time":"$upstream_response_time",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent"'
'}';

# 访问日志
access_log /var/log/nginx/access.log main;
# access_log /var/log/nginx/access.log json;

# 错误日志
error_log /var/log/nginx/error.log warn;

# 按域名分离日志
server {
listen 80;
server_name example.com;

access_log /var/log/nginx/example.com.access.log main;
error_log /var/log/nginx/example.com.error.log warn;
}

# 条件日志
map $status $loggable {
~^[23] 0;
default 1;
}
access_log /var/log/nginx/errors.log main if=$loggable;
}

6.2 日志分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 查看访问日志
tail -f /var/log/nginx/access.log

# 统计访问最多的 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# 统计访问最多的 URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# 统计状态码
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# 统计 404 错误
grep " 404 " /var/log/nginx/access.log

# 统计慢请求(>1s)
awk '($10 > 1) {print $7, $10}' /var/log/nginx/access.log

# 使用 GoAccess 分析
goaccess /var/log/nginx/access.log -o report.html --log-format=COMBINED

# 使用 awk 分析
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10

6.3 状态监控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 启用状态模块
http {
server {
listen 80;
server_name localhost;

# Nginx 状态
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}

# 健康检查
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
}

# 查看状态
curl http://localhost/nginx_status

# 输出示例:
# Active connections: 100
# server accepts handled requests
# 1000000 1000000 5000000
# Reading: 10 Writing: 50 Waiting: 40

6.4 Prometheus 监控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 使用 nginx-prometheus-exporter
# 安装 exporter
docker run -p 9113:9113 nginx/nginx-prometheus-exporter:latest \
-nginx.scrape-uri="http://localhost/nginx_status"

# Prometheus 配置
# prometheus.yml
scrape_configs:
- job_name: 'nginx'
static_configs:
- targets: ['localhost:9113']

# Grafana Dashboard
# 导入 Nginx Dashboard (ID: 12708)

七、故障排查

7.1 常见问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 测试配置
nginx -t
nginx -T

# 重载配置
nginx -s reload

# 查看进程
ps aux | grep nginx

# 查看端口
netstat -tlnp | grep nginx
ss -tlnp | grep nginx

# 查看日志
tail -f /var/log/nginx/error.log
tail -f /var/log/nginx/access.log

# 查看打开的文件
lsof -p $(cat /var/run/nginx.pid)

# 查看系统资源
top -p $(cat /var/run/nginx.pid)

# 测试连接
curl -I http://localhost
curl -v http://localhost

7.2 错误码排查

错误码 含义 常见原因 解决方案
400 错误请求 请求格式错误 检查客户端请求
403 禁止访问 权限不足 检查文件权限、IP 限制
404 未找到 文件不存在 检查路径、root 配置
405 方法不允许 HTTP 方法错误 检查允许的请求方法
413 请求体过大 超过限制 调整 client_max_body_size
414 URI 过长 URL 太长 调整 large_client_header_buffers
499 客户端关闭 客户端超时 优化后端响应时间
500 服务器错误 配置错误 检查 error.log
502 错误网关 后端服务异常 检查后端服务状态
503 服务不可用 后端过载 检查后端负载
504 网关超时 后端响应超时 增加 proxy_read_timeout

7.3 调试技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 增加日志详细程度
error_log /var/log/nginx/error.log debug;

# 调试特定模块
error_log /var/log/nginx/error.log debug_http;
error_log /var/log/nginx/error.log debug_upstream;

# 返回调试信息
location /debug {
return 200 "
remote_addr: $remote_addr
remote_user: $remote_user
request: $request
uri: $uri
args: $args
request_method: $request_method
content_type: $content_type
content_length: $content_length
host: $host
http_host: $http_host
server_protocol: $server_protocol
";
add_header Content-Type text/plain;
}

八、总结

Nginx 配置的关键要点:

  1. 基础配置:worker_processes、worker_connections、keepalive
  2. 常用场景:静态文件、反向代理、负载均衡、HTTPS
  3. 性能优化:缓存、压缩、连接优化
  4. 安全加固:隐藏版本、安全头、访问控制、DDoS 防护
  5. 监控日志:日志格式、状态监控、故障排查

记住:配置要简洁,优化要适度,安全要优先


参考资料: