Nginx-4 Nginx 的7层反向代理
反向代理一般是与负载均衡放在一起谈论的,也会与正向代理作对比
正向代理:客户端知道代理服务器的存在,代替客户端去请求数据,一般需要客户端进行配置
反向代理:一般代理服务集群,客户端不知道代理服务器的存在,代理服务器将客户端请求根据负载均衡策略转发到其中一台服务器进行处理
我们经常会听到说 nginx 的 7 层反向代理与 4 层反向代理,其实就是指 nginx 在 osi 哪个层次提供的反向代理功能

当然 nginx 在读取到应用服务的响应后,可以选择把响应进行缓存,这样在有效期内的相同请求就无需再次请求应用服务器~
反向代理处理流程
反向代理处理流程如下图所示:

根据负载均衡策略选择上游服务器其实就是对应 负载均衡算法,所以负载均衡其实是反向代理中的一个流程
里面有这两个个选项:
bash
Syntax: proxy_request_buffering on | off;
Default: proxy_request_buffering on;
Context: http, server, location
Syntax: proxy_buffering on | off;
Default: proxy_buffering on;
Context: http, server, location
其含义就是在接收到请求后是读取完完整包体再发送给上游服务或客户端,还是边读边发送,默认都是 on,即接收完完整包体再发送
原因是:客户端到 nginx 一般走的是公网,网络一般不太好,如果边读取包体边发送,会导致 nginx 与上游服务建立连接的时间很长,当然如果更追求实时响应而不是并发量,也是可以关掉的
而上游服务一般与 nginx 都在内网,网络较好,但 nginx 与客户端网络较慢,因此也推荐先接收响应包体再发给客户端
修改发往上游的请求
url 路径重写
bash
upstream urlups {
server localhost:8012 weight=1;
}
server {
listen 9001;
location /aaa {
proxy_pass http://urlups; # 注意这里没后缀
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
bash
[root@VM-16-11-centos nginx]# curl localhost:9001/aaa/bbb/ccc
8012 server response
/aaa/bbb/ccc # $uri 变量可以打印
bash
upstream urlups {
server localhost:8012 weight=1;
}
server {
listen 9001;
location /aaa {
proxy_pass http://urlups/www; # 注意这里有后缀
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
bash
[root@VM-16-11-centos nginx]# curl localhost:9001/aaa/bbb/ccc
8012 server response
/www/bbb/ccc # $uri 变量可以打印
也就是如果 proxy_pass 后跟了后缀,会把 location 中匹配的部分进行替换
修改请求的相关内容
开启与上游服务的 keepalive
bash
upstream urlups {
server localhost:8012 weight=1;
keepalive 32;
}
server {
listen 9001;
location /aaa {
proxy_pass http://urlups;
proxy_http_version 1.1; # 设置发往上游服务 version 为 1.1
proxy_set_header Connection ""; # 设置 Connection 为空,为空其实就不传了,但不传的默认就是开启 keepalive
}
}
proxy_set_header、proxy_set_body、proxy_method 等指令都可以修改对应的发往上游服务内容
接收客户端请求包体
在接收请求包体之前,其实会先接收 header,在接收 header 的过程中也会接收一些包体
bash
Syntax: client_body_buffer_size size;
Default: client_body_buffer_size 8k|16k;
Context: http, server, location
- 如果包体非常小,接收 header 时已经接收完了包体,就不需要再分配空间
- 如果剩余包体大小小于
client_body_buffer_size
的大小,就仅分配所需大小 - 否则分配
client_body_buffer_size
大小的内存来接收(不管包体多大,都是通过这个大小的内存一次一次的接收
)- 如果关闭了 proxy_request_buffering,该内存块上的内容就会及时的被发送给上游服务
- 如果开启了 proxy_request_buffering,该内存用完时,会写入临时文件,释放内存
bash
Syntax: client_body_in_single_buffer on | off;
Default: client_body_in_single_buffer off;
Context: http, server, location
client_body_in_single_buffer
的含义是决定 nginx 是否应该将整个客户端请求体保存在单个缓冲区中,如果开启,需要调大 client_body_buffer_size
的值
bash
Syntax: client_max_body_size size;
Default: client_max_body_size 1m;
Context: http, server, location
client_max_body_size
的含义是如果请求头部含有 Content-Length 有效超出最大长度后,返回 413 错误
我之前使用 yapi 导入一个很大的 swagger 文档时就遇到过
bash
Syntax: client_body_temp_path path [level1 [level2 [level3]]];
Default: client_body_temp_path client_body_temp;
Context: http, server, location
Syntax: client_body_in_file_only on | clean | off;
Default: client_body_in_file_only off;
Context: http, server, location
client_body_temp_path
临时文件路径
client_body_in_file_only
包体是否必须存放到文件中,一般用于定位问题,如果开启,即使请求处理完成也还在,clean 会在请求处理完成后删除掉,off 则判断如果包体非常小,少于 client_body_buffer_size
,就不会写入文件
bash
Syntax: client_body_timeout time;
Default: client_body_timeout 60s;
Context: http, server, location
client_body_timeout
两次读取客户端 body 之间的最大时延,而不是整个请求体的传输设置,超出则返回 408 错误
与上游服务建立连接
bash
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location
proxy_connect_timeout
nginx 与上游服务建立连接超时后,会向客户端生成 http 响应,响应码 502
bash
Syntax: proxy_socket_keepalive on | off;
Default: proxy_socket_keepalive off;
Context: http, server, location
proxy_socket_keepalive
TCP 层次的 keepalive,当有一段时间没有收到对方的数据后,发送探测包进行探测,由操作系统实现
bash
# connections 参数设置每个 worker 进程与 upstream server 建立的最多空闲的 keepalive 连接数量。当这个数量被突破时,最近使用最少的连接将被关闭。
Syntax: keepalive connections;
Default: --;
Context: http, server, location
# 1.19 版本之前,默认值是 100,单个长连接上可以执行的请求个数
Syntax: keepalive_requests number;
Default: keepalive_requests 1000;
Context: http, server, location
Syntax: keepalive_timeout timeout [header_timeout];
Default: keepalive_timeout 75s;
Context: http, server, location
具体配置大小可以参考知乎的一个文章:Nginx反向代理配置长连接
bash
Syntax: proxy_bind address [transparent] | off;
Default: ---
Context: http, server, location
这个配置项会修改发往上游服务的 TCP 包中的 Source IP 字段

但是需要保证上游服务的响应能够到我 proxy_bind 定义的 IP,否则响应就丢失了
bash
Syntax: proxy_ignore_client_abort on | off;
Default: proxy_ignore_client_abort off;
Context: http, server, location
Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location
proxy_ignore_client_abort
当客户端关闭连接而不等待响应时(例如,客户端关闭了浏览器或断开了网络连接),Nginx 是否忽略客户端的中断请求。默认 off,不再发送请求
proxy_send_timeout
Nginx 向上游服务发送请求时的超时时间,即在 Nginx 向后端服务器发送请求后,等待后端服务器回应的最大时间。如果超过该时间,Nginx 会关闭连接并返回 504 网关超时错误
接收上游响应
也是非常多的配置项,具体可以参考:nginx-http-proxy模块文档
json
{
proxy_buffer_size: "设置接收响应头的缓冲区大小"
proxy_buffers: "定义缓冲区的数量和大小,用于接收上游服务器响应体"
proxy_buffering: "启用或禁用上游响应的缓冲功能"
proxy_max_temp_file_size: "设置最大允许的临时文件大小"
proxy_temp_file_write_size: "控制每次写入临时文件的数据块大小。"
proxy_temp_path: "指定临时文件存储路径,用于缓存较大的响应"
proxy_busy_buffers_size: "设置正在处理的请求的缓冲区总大小,防止缓冲区溢出影响性能"
proxy_read_timeout: "设置等待上游服务器响应的超时时间,避免长时间等待无响应"
proxy_limit_rate: "限制从 Nginx 到客户端的响应速率,有助于控制带宽使用"
proxy_store: "控制是否将上游响应存储到磁盘,可以用于缓存静态资源"
proxy_store_access: "设置存储响应文件时的访问权限,保护文件的安全性"
}
proxy_buffer_size
-
语法 :
proxy_buffer_size size
-
默认值 :
4k
或8k
,取决于系统架构 -
适用范围 :
http
、server
、location
块 -
含义
:指定用来接收上游响应头部的缓冲区大小。这是 Nginx 在代理请求时,用来存放从上游服务器接收到的 HTTP 响应头部分的内存缓冲区。
- 注意:如果上游服务器响应的头部内容比较大,可以调整这个值以适应更大的响应头。通常情况下,默认值即可,但如果遇到响应头过大或有很多自定义头部时,可以增加缓冲区大小。
proxy_buffers
- 语法 :
proxy_buffers number size
- 默认值 :
8 4k
或8 8k
- 适用范围 :
http
、server
、location
块 - 含义:定义了 Nginx 用于接收上游服务器响应体的内存缓冲区的数量和大小。number 表示缓冲区的数量,size表示每个缓冲区的大小。
- 示例 :
proxy_buffers 16 4k;
表示 Nginx 会为每个请求分配 16 个 4KB 的缓冲区。 - 如果响应体较大,Nginx 会先将响应缓存在内存中,直到这些缓冲区被填满。如果内存缓冲区无法容纳整个响应内容,Nginx 会将响应存储在临时文件中。
- 示例 :
proxy_buffering
- 语法 :
proxy_buffering on | off
- 默认值 :
on
- 适用范围 :
http
、server
、location
块 - 含义:控制 Nginx 是否启用缓冲上游服务器的响应。
on
(默认):Nginx 会缓冲上游响应,将响应存入内存缓冲区(或者临时文件)后,再将其传送给客户端。这有助于提高性能,因为它允许 Nginx 在接收到完整的响应后再将其发送到客户端。off
:Nginx 会直接将上游服务器的响应流式传输给客户端,而不进行缓冲。这通常适用于需要实时流式处理的情况,例如视频流或大文件下载。
proxy_max_temp_file_size
- 语法 :
proxy_max_temp_file_size size
- 默认值 :
1024m
- 适用范围 :
http
、server
、location
块 - 含义:设置临时文件的最大大小,当上游响应体无法完全存储在内存缓冲区时,Nginx 会将其写入磁盘临时文件。此配置项控制了临时文件的最大允许大小。
- 如果响应体超出了这个大小,Nginx 会停止缓存响应并返回错误,通常是
502 Bad Gateway
。因此,可以根据磁盘空间的实际情况调整此值,以避免过大的文件占用过多磁盘空间。
- 如果响应体超出了这个大小,Nginx 会停止缓存响应并返回错误,通常是
proxy_temp_file_write_size
- 语法 :
proxy_temp_file_write_size size
- 默认值 :
8k
- 适用范围 :
http
、server
、location
块 - 含义:定义了写入临时文件时每次写入的块大小。这个配置项控制了当响应体较大,必须写入临时文件时,Nginx 每次写入磁盘的最大数据量。
- 增大该值会减少磁盘写入的次数,可能对性能有益;但是如果临时文件写入时磁盘性能较差或磁盘空间有限,可能会影响性能。
proxy_temp_path
- 语法 :
proxy_temp_path path [level1 [level2 [level3]]]
- 默认值 :
/var/cache/nginx/proxy_temp
- 适用范围 :
http
、server
、location
块 - 含义:指定存放临时缓存文件的路径。Nginx 将在该路径下存储来自上游服务器的响应体,特别是当响应体较大,无法完全缓存到内存中时。
level1
、level2
、level3
:这些选项用于指定子目录的层次结构,可以帮助避免文件名冲突,特别是在高并发情况下。默认的路径proxy_temp_path /var/cache/nginx/proxy_temp;
会将临时文件存放在/var/cache/nginx/proxy_temp
目录下。- 根据磁盘性能和存储空间的需求,您可以自定义此路径,选择更适合的存储位置来提高性能。
proxy_busy_buffers_size
-
语法 :
proxy_busy_buffers_size size
-
默认值 :
8k
或16k
(取决于系统架构) -
适用范围 :
http
、server
、location
块 -
含义:指定用于存储正在处理的请求的缓冲区总大小。当 Nginx 代理请求时,它会将响应内容存入多个缓冲区中。
proxy_busy_buffers_size定义了这些缓冲区的大小上限,特别是当缓冲区被填满时,响应需要等待缓冲区有空间才能继续处理。
- 如果设置的值较小,可能导致频繁的磁盘写入操作(如果开启了
proxy_buffering
),影响性能。增大该值可以避免磁盘 I/O,但也会增加内存占用。
- 如果设置的值较小,可能导致频繁的磁盘写入操作(如果开启了
proxy_read_timeout
- 语法 :
proxy_read_timeout time
- 默认值 :
60s
- 适用范围 :
http
、server
、location
块 - 含义:指定 Nginx 等待从上游服务器读取响应的超时时间。如果上游服务器在这个时间内没有响应,Nginx 会终止请求并返回 504 Gateway Timeout 错误。
- 如果您知道上游服务器响应较慢,可以适当增大这个值。否则,过长的超时会导致等待过久,占用服务器资源。
proxy_limit_rate
- 语法 :
proxy_limit_rate rate
- 默认值:无默认值
- 适用范围 :
http
、server
、location
块 - 含义:限制从 Nginx 到客户端的响应速率,单位通常为字节每秒(bytes/s)。
- 示例 :
proxy_limit_rate 1m;
表示限制响应速率为每秒 1MB。这个配置项通常用于防止大文件或大流量请求对网络带宽产生过大压力,可以实现带宽管理,保护其他请求。
- 示例 :
proxy_store
- 语法 :
proxy_store on | off | path
- 默认值 :
off
- 适用范围 :
http
、server
、location
块 - 含义:控制是否将上游响应内容存储到磁盘中。如果启用,Nginx 会将上游服务器的响应(通常是静态文件)存储到磁盘指定路径下,便于后续的请求直接访问这些缓存的内容。
on
:启用存储,所有响应会被写入磁盘。off
(默认):禁用存储,不会将响应写入磁盘。path
:指定存储路径,响应将写入该路径。
proxy_store_access
- 语法 :
proxy_store_access user:group
- 默认值 :
rw-r--r--
(读写权限为user
,只读权限为group
和others
) - 适用范围 :
http
、server
、location
块 - 含义:设置上游响应被存储到磁盘时的访问权限。该指令用于控制文件的权限,确保只有指定的用户和组可以访问或修改存储的响应文件。
- 示例 :
proxy_store_access user:group;
表示文件的拥有者是user
,文件所属的组是group
,并且根据指定的权限设置文件访问控制。
- 示例 :
Nginx 的功能还是太强大了,可配置项与设计都有很多考量~