0%

Nginx配置详解

Nginx 配置详解:从基础结构到实战优化

Nginx 的灵活性源于其强大的配置系统,通过nginx.conf等文件可实现反向代理、负载均衡、动静分离等核心功能。本文系统拆解 Nginx 配置的结构、核心参数及实战场景,帮助掌握配置逻辑与优化技巧。

Nginx 配置文件体系

Nginx 的配置文件通常包括以下几个核心文件,各司其职:

文件名 作用
nginx.conf 主配置文件,包含全局设置、事件驱动配置及 HTTP 服务核心规则
mime.types 定义文件扩展名与 MIME 类型的映射(如.html对应text/html
fastcgi.conf FastCGI 相关配置(用于连接 PHP 等动态服务)
proxy.conf 反向代理通用配置(如代理头、超时时间)
sites.conf(或sites-enabled/目录) 虚拟主机配置,管理多个网站的独立规则

nginx.conf核心结构

nginx.conf的配置逻辑分为三个层级,从全局到局部逐步细化:全局块 → events 块 → http 块,其中http块可包含多个server块,每个server块又可包含多个location块

1. 全局块:Nginx 整体运行参数

全局块位于配置文件开头,定义影响 Nginx 服务器整体运行的参数,如进程数、日志路径等。

核心配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 运行Worker进程的用户及用户组(默认nobody)
# user www www;

# Worker进程数量(推荐设为CPU核心数,充分利用多核)
worker_processes 4;

# 全局错误日志(路径+级别:debug/info/notice/warn/error/crit)
# error_log /var/log/nginx/error.log error;

# 进程PID文件路径
pid /var/run/nginx.pid;

# 单个Nginx进程可打开的最大文件描述符(需与系统ulimit -n值一致)
worker_rlimit_nofile 65535;

error_log off不是禁用日志,而是创建一个名为off的日志,要禁用日志,可以这么写:error_log /dev/null crit;

关键说明

  • worker_processes:设置为 CPU 核心数可避免进程切换开销,提升并发处理能力;
  • worker_rlimit_nofile:需与系统ulimit -n(默认 1024)保持一致(如 65535),否则会限制最大连接数。

2. events 块:网络连接与事件驱动配置

events块定义 Nginx 与客户端的网络连接规则,如事件模型、最大连接数等,直接影响并发性能。

核心配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
events {
# 事件驱动模型(Linux推荐epoll,Mac推荐kqueue)
# kqueue | rtsig | epoll | /dev/poll | select | poll
use epoll;

# 单个Worker进程支持的最大并发连接数
worker_connections 10240;

# 序列化多进程对新连接的争抢(避免惊群效应,默认on)
accept_mutex on;

# 允许Worker进程同时接收多个新连接(默认off)
multi_accept on;
}

性能关联

  • worker_connections × worker_processes = Nginx 理论最大并发连接数(作为反向代理时需除以 2,因每个连接涉及客户端与后端服务两个连接);
  • use epoll:epoll 是 Linux 内核高效 I/O 模型,支持百万级并发,远超传统select/poll

3. http 块:HTTP 服务核心配置

http块是配置最频繁的部分,包含 HTTP 协议相关的全局设置、虚拟主机(server块)及请求路由(location块)。

(1)http 全局块:HTTP 协议级配置

定义适用于所有虚拟主机的通用规则,如 MIME 类型、日志格式、压缩等。

核心配置示例

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
http {
# 引入MIME类型映射文件
include mime.types;
# 默认文件类型(未知类型时使用)
default_type application/octet-stream;

# 在发送给客户端响应中允许禁用Http1.1标准的块传输编码
chunked_transfer_encoding

#默认编码
#charset utf-8;
#服务器名字的hash表大小
server_names_hash_bucket_size 128;
#请求头大小限制
client_header_buffer_size 32k;
#设定请求缓冲,请求的头信息不能大于该值,否则会报Request URI too Large 414
large_client_header_buffers 4 64k;
#上传文件大小限制
client_max_body_size 8m;

# 开启目录列表访问,合适下载服务器,默认关闭.
# 显示目录
autoindex on;
# 显示文件大小 默认为on,显示出文件的确切大小,单位是bytes 改为off后,显示出文件的大概大小,单位是kB或者MB或者GB
autoindex_exact_size on;
# 显示文件时间 默认为off,显示的文件时间为GMT时间 改为on后,显示的文件时间为文件的服务器时间
autoindex_localtime on;

# 日志格式定义(main为格式名称,可自定义)
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;

# 配置日志是否开启 on|off
access_log off;

# 启用高效文件传输模式(sendfile系统调用,减少IO拷贝)
sendfile on;
# 配合sendfile使用,合并小包发送(提升网络效率)
tcp_nopush on;
# 长连接下禁用Nagle算法(减少延迟,适合实时通信)
tcp_nodelay on;

# 默认为0,每次调用sendfile()传输的数据量最大值,如果设置为0,则没有限制
sendfile_max_chunk 128k;


# 客户端连接超时时间(秒)
keepalive_timeout 65;
# 单个长连接允许的最大请求数
keepalive_requests 100;



# FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度.下面参数看字面意思都能理解.
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;


#gzip压缩
#gzip on;
#允许压缩的页面的最小字节数,页面字节数从header偷得content-length中获取.默认是0,不管页面多大都进行压缩.建议设置成大于1k的字节数,小于1k可能会越压越大
gzip_min_length 1k;
#表示申请4个单位为16k的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果
gzip_buffers 4 16k;
#压缩版本(默认1.1,目前大部分浏览器已经支持gzip解压.前端如果是squid2.5请使用1.0)
gzip_http_version 1.1;
#压缩等级.1压缩比最小,处理速度快.9压缩比最大,比较消耗cpu资源,处理速度最慢,但是因为压缩比最大,所以包最小,传输速度快
gzip_comp_level 2;
#压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn.
gzip_types text/plain application/x-javascript text/css application/xml;
#选项可以让前端的缓存服务器缓存经过gzip压缩的页面.例如:用squid缓存经过nginx压缩的数据
gzip_vary on;

# 负载均衡后端服务器集群定义
upstream backend_servers {
server 192.168.1.101:8080 weight=3; # 权重3,接收更多请求
server 192.168.1.102:8080; # 默认权重1
server 192.168.1.103:8080 backup; # 备份服务器(主服务全挂时启用)
}

# 引入虚拟主机配置(可拆分到sites-enabled目录)
include /etc/nginx/conf.d/*.conf;
}
(2)server 块:虚拟主机配置

一个http块可包含多个server块,每个server块代表一个虚拟主机(网站),通过listenserver_name区分不同域名或端口。

核心配置示例(基于域名的虚拟主机)

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
server {
# 监听端口(默认80,HTTPS为443)
listen 80;
# 绑定域名(可多个,空格分隔)
server_name example.com www.example.com;

# 字符集(如中文网站需设置utf-8)
charset utf-8;

# 该虚拟主机的访问日志
access_log /var/log/nginx/example.access.log main;

# 根路径请求处理
location / {
# 网站根目录
root /var/www/example.com;
# 默认索引文件
index index.html index.htm;
}

# 动态请求反向代理到后端集群
location ~ \.php$ {
proxy_pass http://backend_servers; # 指向upstream定义的集群
proxy_set_header Host $host; # 传递客户端Host头
proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端IP
}

# 错误页面配置
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/error_pages;
}
}

(3)location 块:请求路由与匹配规则

location块用于匹配客户端请求的 URI,执行特定处理(如返回静态文件、反向代理)。其核心是匹配规则,决定请求由哪个 location 处理。

匹配规则优先级(从高到低)

修饰符 规则 示例
= 精确匹配 URI location = /login 仅匹配/login
^~ 前缀匹配(优先于正则) location ^~ /static 匹配以/static开头的 URI
~ 区分大小写的正则匹配 location ~ \.jpg$ 匹配.jpg结尾的 URI(不匹配.JPG
~* 不区分大小写的正则匹配 location ~* \.jpg$ 匹配.jpg.JPG结尾的 URI
无修饰符 前缀匹配(普通) location /blog 匹配以/blog开头的 URI

location有多种匹配规则[=|~|~*|^~|@] /url/

  • 没有修饰符表示必须以指定模式开头

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 匹配以/abc开头的
    location /abc {

    }
    # 以/abc开头的
    http://zhhll.com.cn/abc
    http://zhhll.com.cn/abc?id=11
    http://zhhll.com.cn/abc/
    http://zhhll.com.cn/abcd
  • =表示精确匹配,优先级最高

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 仅匹配/abc,可以有参数
    location = /abc {

    }
    # 可以匹配
    http://zhhll.com.cn/abc
    http://zhhll.com.cn/abc?id=11
    # 不能匹配
    http://zhhll.com.cn/abc/
    http://zhhll.com.cn/abcd
  • \^~ 类似于无修饰符,表示uri以某个字符串开头,即^~/spring/ 可以被所有以/spring/开头的匹配到

  • ~为区分大小写的正则匹配,如果使用!~则表示取反,不匹配的正则

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    location ~ /abc {

    }
    # 可以匹配
    http://zhhll.com.cn/abc
    http://zhhll.com.cn/abc?id=11
    # 不能匹配
    http://zhhll.com.cn/Abc
    http://zhhll.com.cn/abc/
    http://zhhll.com.cn/abcd
  • ~*为不区分大小写的正则匹配,如果使用!~*则表示取反,不匹配的正则

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    location ~* /abc {

    }
    # 可以匹配
    http://zhhll.com.cn/abc
    http://zhhll.com.cn/abc?id=11
    http://zhhll.com.cn/Abc
    # 不能匹配
    http://zhhll.com.cn/abc/
    http://zhhll.com.cn/abcd
  • / 通用匹配,任何请求都会匹配到

  • @ 客户端不能访问,只能由内部产生的请求来访问

静态文件路径

可以使用root或alias来指定静态资源文件路径,root可以配置在http块、server块、location块以及if块中,alias只能配置在location块中

root

使用root来表示请求的url时会进行完整的拼接,即如果请求使用的uri是/pic/index.html的话,使用root实际获取的是/data/www/web/pic/index.html

1
2
3
location /pic/ {
root /data/www/web;
}

alias

alias会将location中配置的路径丢弃掉,即如果请求使用的uri是/pic/index.html的话,使用alias实际获取的是/data/www/web/index.html

1
2
3
location /pic/ {
alias /data/www/web;
}

常用场景配置

  • 静态资源处理

    1
    2
    3
    4
    5
    6
    # 匹配静态文件(图片、CSS、JS)
    location ~* \.(jpg|jpeg|png|css|js)$ {
    root /var/www/static;
    expires 7d; # 缓存7天,减少重复请求
    add_header Cache-Control "public, max-age=604800";
    }
  • 禁止访问敏感文件

    1
    2
    3
    4
    5
    6
    7
    # 禁止访问.htaccess和.git目录
    location ~ /\.ht {
    deny all; # 返回403 Forbidden
    }
    location ~ /\.git {
    deny all;
    }
  • 反向代理与负载均衡

    1
    2
    3
    4
    5
    6
    # 所有API请求代理到后端服务
    location /api {
    proxy_pass http://backend_servers;
    proxy_connect_timeout 30s; # 代理连接超时
    proxy_read_timeout 60s; # 代理读取超时
    }

实战配置技巧与优化

性能优化参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 全局块优化
worker_processes 4; # 等于CPU核心数
worker_rlimit_nofile 65535;

# events块优化
events {
use epoll;
worker_connections 10240; # 单个Worker支持10k连接
}

# http块优化
http {
open_file_cache max=102400 inactive=20s; # 缓存打开的文件句柄
open_file_cache_valid 30s; # 缓存验证时间
client_max_body_size 10m; # 上传文件大小限制
sendfile on;
tcp_nopush on;
}

安全加固

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 隐藏Nginx版本号
server_tokens off;

# 限制特定IP访问
location /admin {
allow 192.168.1.0/24; # 允许内部网段
deny all; # 拒绝其他IP
}

# 防盗链(仅允许指定域名引用资源)
location ~* \.(jpg|png)$ {
valid_referers none blocked example.com *.example.com;
if ($invalid_referer) {
return 403;
}
}

依据UA屏蔽爬虫

1
2
3
4
if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou
spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot") {
return 403;
}

屏蔽IP访问

1
2
3
4
allow 133.27.182.82;
allow 113.106.18.0/24;
allow 121.201.104.0/24;
deny all;

使用Auth权限访问

1
2
auth_basic "bbs-auth";
auth_basic_user_file /usr/local/nginx/conf/bbsauthpwd;

限制带宽

1
2
3
4
5
# 用户下载达到 500k 后,便控制其速度在 50k 以内
location /download/ {
limit_rate_after 500k;
limit_rate 50k;
}

限制连接

1
2
3
4
5
6
7
8
9
10
# 定义了一个名为“down”,10M大小,以连接IP为key的连接数据存储空间
limit_conn_zone $binary_remote_addr zone=down:10m;

# 读取名为`down`连接数据存储空间的数据,限制每个key(上面是以ip作为IP) 最大同时连接数为4
location ~ .*\.(rar|zip|apk)?$ {
limit_conn down 4;
limit_rate 150k;
}

limit_conn_log_level notice: 指定当触发limit的时候日志打印级别

限制请求

1
2
3
4
5
6
# 定义一个名为”one”, 10M大小,每秒1个请求的请求数据存储空间
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

# 引用名为“one”的存储空间,burst为等待请求数量数,当等待请求数量超过50个时,则抛出503错误,nodelay 针对的是 burst 参数,burst=50 nodelay 表示这50个请求立马处理,不能延迟,相当于特事特办。不过,即使这20个突发请求立马处理结束,后续来了请求也不会立马处理。burst=50 相当于缓存队列中占了50个坑,即使请求被处理了,这20个位置这只能按 100ms一个来释放
limit_req zone=one burst=50 nodelay;
limit_req_log_level notice: 指定当触发limit的时候日志打印级别

实时显示Nginx运行状况

在安装nginx是编译http_stub_status_module即可,使用参数为–with-http_stub_status_module

1
2
3
4
location /ngx_status {
stub_status on;
access_log on;
}

设置错误页面

1
error_page 404 /404.html

在负载均衡里面,实现后端服务器故障转移的配置

1
2
3
4
5
6
location ~ \.(jsp)$ {
proxy_next_upstream http_502 http_504 timeout;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://server_pool;
}

常见错误码与排查

错误码 可能原因 排查方向
403 Forbidden 权限不足、被deny拦截 检查文件权限、location规则
404 Not Found 文件不存在、路径错误 检查root/alias配置、URI 匹配
413 Request Entity Too Large 上传文件超过client_max_body_size 调大client_max_body_size
502 Bad Gateway 后端服务未启动或无响应 检查proxy_pass指向的服务状态
504 Gateway Timeout 后端服务处理超时 调大proxy_read_timeout

Nginx常见配置参数

  • server_names_hash_max_size 1024;
  • server_names_hash_bucket_size 512;
  • client_header_buffer_size 32k; # 客户端请求头部的缓冲区大小,有时候请求头过大,可以适时增大该配置
  • large_client_header_buffers 4 32k;
  • client_max_body_size 10m;#设置最大的允许客户端请求主体的大小(上传文件大小限制),默认为1m,如果大于该设置,会返回413
  • client_body_buffer_size 128k; 为了阻止临时文件写到磁盘,可以通过该指令为客户端请求体设置缓存大小
  • client_body_in_single_buffer 为了减少拷贝操作,该指令强制nginx将整个客户端请求体保存在单个缓存中
  • client_body_temp_path 定义一个路径用于保存客户端请求体
  • keepalive_timeout 60; #客户端连接超时时间,单位是秒,默认是75秒
  • client_header_timeout #设置请求头的超时时间,可以设置低些,如10秒
  • client_body_timeout #设置请求体的超时时间,可以设置低些,如10秒
  • reset_timeout_connection #关闭不响应的客户端连接,这将会释放那个客户端所占有的内存空间,建议开启
  • send_timeout #指定客户端的响应超时时间,如果在两次客户端读取操作之间,客户端没有读取任何数据,Nginx就会关闭连接,默认是60秒,可以设置小一些,如10秒
  • sendfile on; # 开启高效传输模式(开启或禁用sendfile函数),默认为off
  • tcp_nopush on; #将文件一次性一起传输给客户端,提高网络包的传输效率,建议开启
  • tcp_nodelay on; #此时nginx不缓存数据,一段一段的发送(允许或禁止TCP_NODELAY),仅适用于keep-alive连接
  • ssi on; # 开启ssi支持,默认为false
  • ssi_silent_errors on; # 设置为on表示在处理ssi文件时不输出错误信息,默认为false
  • ssi_types text/html; # 默认支持html 如果需要支持shtml(服务器执行脚本),需要设置为ssi_types text/shtml
  • server_tokens off; # 关闭nginx版本号的显示,默认为on

Nginx优化相关参数

  • worker_processes 2; # 配置生成的worker process数量,进程数,一般为cpu核数
  • worker_rlimit_nofile 65536; # 一个nginx进程打开的最多文件描述符数目,一般设置为与系统设定的值相同(ulimit -n)
  • worker_cpu_affinity 01 10;# 为每个进程分配CPU的工作内核
  • use epoll; # 使用epoll的IO模型,epoll是linux内核为处理大量文件描述符而做了改进的poll,它能显著提高程序在大量连接中只有少数活跃的情况下的CPU利用率
  • worker_connections 1024 # 每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为worker_processes*worker_connections
  • keepalive_timeout 60 #keepalive超时时间,客户端到服务端的连接持续有效时间,当出现对服务器的后继请求时,可以避免重新建立连接
  • client_header_buffer_size 4k 客户端请求头部的缓冲区大小,可以根据系统分页大小来设置,一般一个请求的头部大小不会超过1k
  • open_file_cache max=102400 inactive=20s 为打开文件指定缓存,默认没有启用,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没有请求后删除缓存
  • open_file_cache_vaild 30s 这个是指多长时间检查一次缓存的有效信息
  • open_file_cache_min_uses 1 open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,将被移除

欢迎关注我的其它发布渠道