Nginx配置文件学习【一】
默认的Nginx配置文件
events {
worker_connections 1024;
}
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;
# 修正超时指令的语法(移除了非ASCII空格)
client_header_timeout 15; # 读取客户端请求头的超时时间
client_body_timeout 15; # 读取客户端请求体的超时时间
send_timeout 60; # 向客户端发送响应的超时时间
keepalive_timeout 65; # 长连接超时时间
keepalive_requests 100; # 每个长连接允许的最大请求数
server_tokens off; # 隐藏Nginx版本信息
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
sendfile
tcp_nodelay on|off :在keepalived模式下的连接是否启用TCP_NODELAY选项;
tcp_nopush on|off:在sendfile模式下,是否启用TCP_CORK选项;
sendfile on|off:是否启用sendfile功能;
通常情况下以上三项都是打开的,TCP_NODELAY主要是发送报文延时问题,如果开启了该功能选项,表示不管数据包多小都及时发送,如果关闭了,通常会等到一定量的数据报文一起发送,对于小报文延时就很高,TCP_CORK主要是解决小包问题,它和TCP_NODELAY相反,启用表示要到一定量的数据包后才发送,关闭表示不用等一定量的数据报文再发送,它们两者都是解决小包问题,前者应用在长连接模式下,后者应用在sendfile模式下;sendfile模式解决了内核到用户应用程序,用户应用程序到内核的重复过程,它可将数据报文直接从内核加载到网卡socket缓存区,直接发送出去;这三项都和性能相关,通常都是开启的;
压缩gzip
:::danger
ngx_http_gzip_module:使用gzip方式压缩响应报文大小
:::
1.什么是压缩
用户请求的内容在发送到客户端之前,Nginx服务器会根据一些具体的策略实施压缩,以节约网站出口带宽,同时加快了数据的传输效率。
2.需要压缩和不需要压缩的对象:
1.一般文本的压缩比都是非常高的,类似:html,css,js,xml等格式的文件
2.被压缩的纯文本至少要大于1KB,否则没必要进行压缩。
3.图片,视频等尽量不要压缩,这类格式的文件一般都是经过压缩的,再压缩体积也不会减少很小,反而是消耗大量的CPU,内存等资源。
3.该功能依赖于ngx_http_gzip_module模块。默认安装。
server {
listen 80;
server_name 192.168.0.30;
root /data/web/html;
gzip on;
gzip_types text/xml text/plain;
#firefox浏览器去访问状态页数没有启用gzip压缩,
gzip_disable "Firefox";
location /basic_status {
stub_status;
auth_basic "please input you username and passwd login";
auth_basic_user_file /etc/nginx/conf.d/.ngxpasswd;
}
}
验证结果:
参数说明如下:
gzip on; #开启gzip压缩功能
gzip_min_length 1k;
#设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取,默认值是0,表示不管页面多大都进行压缩,建议设置成大于1K,如果小于1K可能会越压越大
gzip_buffers 4 16k;
#压缩缓冲区大小,表示申请4个单位为16K的内存作为压缩结果流缓存,默认是申请与原始是数据大小相同的内存空间来存储gzip压缩结果;
gzip_http_version 1.1
#压缩版本(默认1.1 前端为squid2.5时使用1.0)用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP压缩,使用默认即可。
gzip_comp_level 2;
#压缩比率,用来指定GZIP压缩比,1压缩比最小,处理速度最快;9压缩比最大,传输速度快,但处理最慢,也消耗CPU资源
gzip_types text/css text/xml application/javascript;
#用来指定压缩的类型,“text/html”类型总是会被压缩,这个就是HTTP原理部分讲的媒体类型。
gzip_vary on;
#vary hear支持,该选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用缓存经过Nginx压缩的数据。
location块匹配规则
location [modifier] URI {
}
其中,modifier是可选的,用于指定匹配类型,常见的有:
=
:精准匹配
^~
:前缀匹配
~
:区分大小写的正则匹配
~*
:不区分大小写的正则匹配
无修饰符
:前缀匹配
配置示例 :
location ^~ /static/ {
root /var/www/static;
}
这个配置块会在URI以/static/开头时生效。
localtion ~ \.php& {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|png|gif|ico)$ {
root /var/root/images;
}
第一个 location
块用于匹配以 .php
结尾的 URI,第二个 location
块用于匹配图片文件,且不区分扩展名的大小写。
location /匹配规则
在 Nginx 的 location
块中,路径末尾的斜杠(/
)是否添加会影响匹配行为和请求处理逻辑,尤其是在涉及目录匹配、文件查找和内部重定向时。下面详细分析:
一、普通前缀匹配(无修饰符)
1. 路径末尾加斜杠(如 /path/
)
- 匹配规则:只匹配以
/path/
开头的 URI(必须包含斜杠)。 - 应用场景:通常用于匹配目录,例如静态资源目录。
- 示例:
location /images/ {
root /data/www/;
}
- 请求 `/images/logo.jpg` 会被匹配,实际文件路径为 `/data/www/images/logo.jpg`。
- 请求 `/images`(无斜杠)**不会被匹配**,可能会落入其他 location(如通用匹配)。
2. 路径末尾不加斜杠(如 /path
)
- 匹配规则:匹配以
/path
开头的 URI,无论是否包含斜杠。 - 应用场景:用于匹配目录或文件,例如 API 前缀或固定页面。
- 示例:
location /api {
proxy_pass http://backend;
}
- 请求 `/api/users` 和 `/api/` 都会被匹配。
二、精确匹配(=
修饰符)
1. 路径末尾加斜杠(如 =/path/
)
- **必须严格匹配 **
/path/
(包含斜杠)。 - 示例:
location = /admin/ {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/htpasswd;
}
- 请求 `/admin/` 会触发认证,而 `/admin` 不会。
2. 路径末尾不加斜杠(如 =/path
)
- **必须严格匹配 **
/path
(不含斜杠)。 - 示例:
location = /health {
return 200 'OK';
}
- 请求 `/health` 会返回 `200 OK`,而 `/health/` 会落入其他 location。
三、正则匹配(~
和 ~*
)
路径末尾的斜杠会影响正则表达式的匹配结果
- 示例 1:匹配所有
.jpg
文件(无论路径)
location ~* \.jpg$ {
expires 7d;
}
- `/images/logo.jpg` 匹配成功,`/images/logo.jpg/` 匹配失败(因为 URI 以斜杠结尾)。
- 示例 2:强制要求目录结尾
location ~ ^/directory/.*\/$ {
# 只匹配以 /directory/ 开头且以斜杠结尾的 URI
}
四、实际应用中的差异
1. 目录 vs 文件
- 目录匹配:建议加斜杠(如
/static/
),避免误匹配文件。
location /static/ {
# 只处理 /static/ 目录下的文件,不处理 /static-file
}
- 文件匹配:不加斜杠(如
/favicon.ico
)。
location = /favicon.ico {
access_log off;
}
2. 自动补全斜杠
- 若请求
/directory
(无斜杠)但实际是目录,Nginx 可能会自动重定向到/directory/
(需配置autoindex on
或使用try_files
)。
location /directory {
try_files $uri $uri/ =404;
}
3. 反向代理场景
- 路径末尾的斜杠会影响
proxy_pass
的路径拼接:
# 配置 A:proxy_pass 末尾有斜杠
location /api/ {
proxy_pass http://backend/; # 请求 /api/users → http://backend/users
}
# 配置 B:proxy_pass 末尾无斜杠
location /api/ {
proxy_pass http://backend; # 请求 /api/users → http://backend/api/users
}
五、总结与建议
场景 | 路径末尾是否加斜杠 | 示例 | 说明 |
---|---|---|---|
匹配目录 | 加斜杠(/ ) |
location /static/ { ... } |
确保只匹配目录下的文件,避免误匹配 /static-file 。 |
匹配固定文件或路径 | 不加斜杠 | location = /health { ... } |
精确匹配 /health ,排除 /health/ 。 |
正则匹配文件扩展名 | 不加斜杠 | location ~ \.jpg$ { ... } |
匹配 .jpg 文件,排除 .jpg/ (通常不存在)。 |
反向代理(保留路径前缀) | 不加斜杠 | proxy_pass http://backend; |
请求 /api/users 会转发到 http://backend/api/users 。 |
反向代理(去除路径前缀) | 加斜杠 | proxy_pass http://backend/; |
请求 /api/users 会转发到 http://backend/users 。 |
核心原则:
- 明确区分目录和文件,目录加斜杠,文件不加。
- 使用
=
修饰符时,严格匹配斜杠的有无。 - 正则表达式中,根据需求使用
^
和$
锚定路径边界。
root和alias的使用
这表示当我们访问”/demo”这个url时,实际访问的是服务器的”/opt/test/demo”目录
location /demo1 {
alias /opt/test;
}
上例配置表示,当我们访问”/demo1/nginx1.jpg”时,其实就是在访问服务器的” /opt/test/nginx1.jpg”,也就是说,当我们使用alias时,location的url是与alias的路径完全对等的。
前者是拼接,后者是别名。
链接超时相关的参数
什么是链接超时?
当服务器之间建立的链接没有收到处理请求时,会在指定的时间内让他超时自动退出而不是死等。
超时设置的作用:
1.无用的链接尽快超时,减少资源 消耗。
2.避免黑客或者恶意攻击。
超时的参数设置
client_header_timeout 15; # 读取客户端请求头的超时时间
client_body_timeout 15; # 读取客户端请求体的超时时间
send_timeout 60; # 向客户端发送响应的超时时间
keepalive_timeout 65; # 长连接超时时间
keepalive_requests 100; # 每个长连接允许的最大请求数
Nginx站点目录及文件URI访问控制
配置Nginx,限制禁止解析指定目录下的指定程序文件。
location ~ ^/static/.*\.(php|ph)$ {
deny all;
}
location ~* ^/data/(attachment|avater)/.*\.(php|php5) $ {
deny all;
}
禁止访问指定目录并返回状态码
location /admin/ { return404;}
location /templates/ { return 403;}
conf配置:
location /static/.*\.txt$ {
#root /usr/share/nginx/html;
return 404;
}
日志返回:
192.168.232.1 - - [22/Jul/2025:04:28:04 +0000] "GET /static/1.txt HTTP/1.1" 404 178 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 QuarkPC/4.2.5.444" "-"
192.168.232.1 - - [22/Jul/2025:04:28:04 +0000] "GET /static/1.txt HTTP/1.1" 404 178 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 QuarkPC/4.2.5.444" "-"
2.限制网站来源ip的访问
:禁止指定目录被外界访问,但只允许指定ip访问该目录
location ~ ^/static/ {
allow 192.168.232.180;
deny all;
}
结果:
192.168.232.1 - - [22/Jul/2025:04:41:41 +0000] "GET /static/1.jpg HTTP/1.1" 403 177 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 QuarkPC/4.2.5.444" "-"
192.168.232.128 - - [22/Jul/2025:04:42:05 +0000] "GET /static/1.jpg HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0" "-"
控制客户端请求Nginx的速率
:::info
ngx_http_limit_req_module 这个模块用于限制每个IP访问定义key的请求速率。
:::
参数如下:
limit_req_zonekey zone=name:size rate=rate;
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#以请求的客户端IP作为key值,内存区域命名为one,分配10m内存空间,访问速率限制为1秒1次请求
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
listen 80;
server_name www.etiantian.org;
location ~ /static/.*\.(pdf|txt)$ {
#使用前面定义的名为one的内存空间
limit_req zone=one;
#limit_req zone=one burst=5 nodelay;
root /usr/share/nginx/html;
}
}
}
使用wrk进行测试:
apt-get install wrk
wrk -t2 -c10 -d10s http://192.168.232.130/static/pdf.pdf
Thread Stats Avg Stdev Max +/- Stdev
Latency 0.90ms 1.43ms 31.17ms 95.48%
Req/Sec 6.85k 1.69k 11.29k 64.50%
136425 requests in 10.03s, 173.11MB read
Non-2xx or 3xx responses: 136414
Requests/sec: 13597.98
Transfer/sec: 17.25MB
这个工具没怎么研究过,不过根据结果关键数据可以看出10s的测试时间,136425-136414=11次成功。,满足设置的配置1s1次的请求。
日志输出也满足:
控制Nginx并发连接数
:::info
nginx_http_limit_conn_module 这个模块用于限制每个定义的key值的连接数,特别是单IP的连接数。
:::
工作原理:
基于 IP 限制:Nginx 会跟踪每个客户端 IP 的并发连接数。
超出限制的处理:当某个 IP 的连接数超过阈值时,新请求会被拒绝,并返回 503 Service Temporarily Unavailable 错误。
参数说明如下:
limit_conn_zone参数:
语法:limit_conn_zone key zone=name:size;
上下文:http
用于设置共享内存区域,key可以是字符串,nginx自有变量或前两个组合,如$binary_remote_addr、$server_name。name为内存区域的名称,size为内存区域的大小。
limit_conn参数:
语法:limit_conn zone number;
上下文:http、server、location
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#以请求的客户端IP作为key值,内存区域命名为addr,分配10m内存空间,
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
listen 80;
server_name www.etiantian.org;
location ~ /static/.*\.(pdf|txt)$ {
# limit_req zone=one; # 注释掉的请求速率限制
limit_conn addr 1; # 连接数限制:每个IP最多1个并发连接
root /usr/share/nginx/html; # 静态文件根目录
}
}
}
参数补充:
- 过严的限制影响用户体验:
- 若用户同时打开多个
.pdf
链接(如浏览器多标签),后续请求会被拒绝。 - 建议根据业务调整并发数(如
limit_conn addr 3
允许 3 个并发)。
- 若用户同时打开多个
- 缺少速率限制:
- 当前仅限制并发连接,未限制单位时间内的请求次数(如 1 秒内请求 10 次)。
- 如需补充,可启用注释的
limit_req
(需先定义zone=one
):
limit_req zone=one burst=2; # 每秒1个请求,允许2个突发
- 未限制总连接数:
- 可增加
limit_conn_zone
对服务器总连接数限制(如限制所有 IP 的总并发):****
- 可增加
limit_conn_zone $server_name zone=total:10m; # 按服务器名定义总连接区域
limit_conn total 100; # 服务器总并发连接不超过100
结果验证:
wrk -c2 -d1s http://192.168.232.130/static/pdf.pdf
Running 1s test @ http://192.168.232.130/static/pdf.pdf
2 threads and 2 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 265.68us 789.01us 13.17ms 97.32%
Req/Sec 6.37k 0.91k 7.90k 71.43%
13300 requests in 1.10s, 28.25MB read
Non-2xx or 3xx responses: 13298
Requests/sec: 12089.34
Transfer/sec: 25.68MB