Nginx 应用

Nginx 作为反向代理

反向代理服务器介于用户和真实应用服务器之间,提供请求和响应的中转服务

对于用户而言,访问反向代理服务器就是访问真实服务器

反向代理可以有效降低服务器的负载消耗,提升效率

反向代理的作用

隐藏真实服务器

便于横向扩展后端动态服务

动静分离,提高系统健壮性

动静分离

在web服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提升整个服务访问性能和可维护性。

upstream 模块

参数

upstream 段名,以 { 开始 ,}结束 中间定义上游服务的URL

server 定义上游服务地址

zone 定义共享内存,用于跨worker子进程

keepalive 对上游服务启用长连接

keepalive_requests 一个长连接最多请求个数

keepalive_timeout 空闲情况下,一个长连接的超时时长

hash 哈希负载均衡算法

ip_hash 依据IP进行哈希负载均衡算法

least_conn 最少连接数

least_time 最短响应时间

random 随机负载均衡

upsteam 设置

1
2
3
4
5
6
7
8
9
10
upstream name {
server address [parameters] ;
# parameters 可选值
# weight = number 权重值, 默认为1
# max_conns = number 上游服务器的最大并发连接数
# fail_timeout = time 服务器不可用的判定时间
# max_fails = number 服务器不可用的检查次数
# backup 备份服务器,仅当其他服务器都不可用时
# down 标记服务器长期不可用,离线维护
}

配置示例 :

1
2
3
4
5
6
7
8
9
10
11
12
13
upstream {
server 127.0.0.1:8080 weight=3 max_conns=1000 fail_timeout=10s max_fails = 2
keepalive 32;
keepalive_request 50;
keepalive_timeout 30s;
# 设置了权重为3 ,
# 与上层应用服务器的最大连接是1000,
# 失败超时时间为10s
# 失败尝试为2次
# 保持长连接的连接数为32
# 长连接最大请求为50
# 长连接超时时间为30s
}

反向代理设置

创建子系统配置项

1
2
3
4
5
6
7
8
9
10
11
12
upstream back_end {
server 192.168.184.20:8080 weight = 2 max_conns = 1000 fail_timeout= 10s max_fails=3;
keepalive 32 ;
keepalive_requests 80 ;
keepalive_timeout 20s ;
server {
listen 80 ;
server_name proxy.codfish.cn ;
location /proxy {
proxy_pass http://back_end/proxy ;
}
}

proxy_pass

不带/意味着Nginx不会修改用户URL,而是直接透传给上游的应用服务器

1
2
3
4
5
6
location /bbs/ {
proxy_pass <http://127.0.0.1:8080>;
}
-> 用户请求URL :/bbs/abc/test.html
-> 请求到达Nginx的URL :/bbs/abc/test.html
-> 请求到达上游应用服务器的URL :/bbs/abc/test.html

带/意味着Nginx会修改用户URL,修改方法:将location后的URL从用户URL中删除

1
2
3
4
5
6
location /bbs/ {
proxy_pass <http://127.0.0.1:8080/>;
}
-> 用户请求URL :/bbs/abc/test.html
-> 请求到达Nginx的URL :/bbs/abc/test.html
-> 请求到达上游应用服务器的URL :/abc/test.html

Proxy_request_buffering on | off

会对请求进行缓存,在请求体数据完整之后再进行数据转发

适用场景 :

吞吐量要求高

上游服务并发处理能力低

Proxy_request_buffering off

适用场景 :

更及时的响应

减少Nginx磁盘IO

client_max_body_size size 请求体的最大尺寸 → 返回413错误

client_body_buff_size size 请求体的尺寸在内存缓存 → 在磁盘开辟空间存储

client_body_in_single_buffer 请求体尽可能存储到一块连续空间

client_body_temp_path 指定磁盘目录

client_body_in_file_only 直接将请求体存入磁盘 on | clean | off clean会在处理完成后清除请求

client_body_timeout 请求不发送的超时时间

proxy_method 修改请求方法名

proxy_http_version 修改请求协议声明

proxy_set_header 设置请求头部

proxy_pass_request_header on | off 代理直接转发头部信息到应用服务器

proxy_set_body 设置包体

proxy_pass_request_body on | off 代理直接转发请求体到应用服务器

proxy_connect_timeout time 指定与应用服务器连接超时时间

proxy_socket_keepalilve on | off

proxy_send_timeout time 请求未发送超时时间

proxy_ignore_client_bort on | off 用户断开后,Nginx与后端的连接选项

负载均衡

负载均衡配置

1
2
3
4
5
6
7
8
9
10
11
12
13
upstream demo_server {
server 192.168.184.20:8020;
server 192.168.184.20:8021;
server 192.168.184.20:8022;
}

server {
listen 80;
server_name balance.kutian.edu ;
location /balance/ {
proxy_pass http://demo_server ;
}
}

哈希算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
**hash**  key [consistent] 

upstream demo_server {
hash $request_uri ;
server 192.168.184.20:10020 ;
server 192.168.184.20:10010 ;
}

server {
listen 80 ;
server_name balance.codfish.cn ;
locations/ {
proxy_pass http://demo_server_1 ;
}
}

IP_哈希算法

1
2
3
4
5
6
7
8
9
10
11
12
upstream demo_server {
ip_hash ;
server 192.168.184.20:10020 ;
server 192.168.184.20:10010 ;
}

server {
listen 80 ;
server_name balance.codfish.cn ;
locations/ {
proxy_pass http://demo_server_1;
}

最少连接数算法

1
2
3
4
5
6
7
8
9
10
11
12
13
upstream demo_server {
zone test 10M;
least_conn;
server 192.168.184.20:10020 ;
server 192.168.184.20:10010 ;
}

server {
listen 80 ;
server_name balance.codfish.cn ;
locations/ {
proxy_pass http://demo_server_1;
}

轮询

1
2
3
4
5
6
7
8
9
10
11
upstream demo_server {
server 192.168.184.20:10020 ;
server 192.168.184.20:10010 ;
}

server {
listen 80 ;
server_name balance.codfish.cn ;
locations/ {
proxy_pass http://demo_server_1;
}

权重轮询

1
2
3
4
5
6
7
8
9
10
11
upstream demo_server {
server 192.168.184.20:10020 weight=2 ;
server 192.168.184.20:10010 weight=1 ;
}

server {
listen 80 ;
server_name balance.codfish.cn ;
locations/ {
proxy_pass http://demo_server_1;
}

响应时间 (通过第三方模块加载)

1
2
3
4
5
6
7
8
9
10
11
12
upstream demo_server {
fair
server 192.168.184.20:10020 ;
server 192.168.184.20:10010 ;
}

server {
listen 80 ;
server_name balance.codfish.cn ;
locations/ {
proxy_pass http://demo_server_1;
}

转发容错

1.通过一些字段控制,当nginx收到服务器的错误响应后,将请求向其他服务器转发

1
2
3
4
5
6
proxy_next_upstream error  # 出现异常后,分发请求
timeout # 后端服务器响应超时后,分发请求
invalid_header # 后端服务器响应不可用报文头后,分发请求
http_xxx # 后端响应异常状态码后,分发请求
non_idempotent # 非幂等请求失败后,是否进行转发
off # 关闭分发

2.服务器响应超时/失败多次,调度请求给其他服务器

1
2
proxy_next_upstream_timeout times ;  # 后端服务器响应超时时间设置
proxy_next_upstream_tries ; # 后端服务器多次尝试请求失败后,默认为0 即允许无数次尝试

3.服务器响应存在错误,直接转发给客户端

1
proxy_intercept_errors  on | off

缓存

通过在边缘阶段的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
**proxy_cache  zone | off                                     # 开启nginx 缓存

proxy_cache_path path # 缓存文件的存放路径
[level=levels] # 指定目录层级
[use_temp_path=on/off] # off直接使用path路径 on是临时路径
keys_zone=name:size # name是共享内存名称;size是共享内存大小
[inactive=time] # 在指定时间内没有被访问缓存会被清理
[max_size=size] # 设定最大的缓存文件大小
[manager_files=number] # CM清理一次缓存文件,最大清理文件数
[manager_sleep=time] # CM清理一次后进程的休眠时间
[manager_threshold=time] # CM清理一次的最长耗时,最长50ms
[loader_files=number] # CL载入文件到共享内存,每批最多文件数
[loader_sleep=time] # CL加载缓存文件到内存后,进程休眠时间
[loader_threshold=time] # CL加载缓存文件到共享内存的最大耗时
[purger=on | off]
[purger_files=number]
[purger_sleep=time]
[purger_threshold=time]
proxy_cache_key
proxy_cache_valid # 定义对哪些状态进行响应

upstream_cache_status # 检查缓存是否命中
# MISS # 未命中
# HIT # 命中
# EXPIRED # 缓存过期
# STALE # 命中了陈旧缓存
# REVALIDDATED # 验证后依然有效
# UPDATING # 缓存正在更新
# BYPASS # 响应从原始服务器获取**

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
proxy_cache_path /opt/nginx/cache_temp levels=2:2 keys_zone=cache_zone:30m max_size=32g inactive=60m
use_temp_path=off;

upstream cache_server{
server 192.168.184.20:1010 ;
server 192.168.184.20:1011 ;
}

server {
listen 80 ;
server_name cache.codfish.cn ;
location / {
proxy_cache cache_zone ;
proxy_cache_valid 200 5m ;
add_header Nginx-Cache-Status "$upstream_cache_status";
proxy_pass http://cache_server;
}

}

特定内容不适用缓存

1
2
**proxy_no_cache string ;                              # 不使用缓存
proxy_cache_bypass string ; # 直接交给应用服务器**

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
proxy_cache_path /opt/nginx/cache_temp levels=2:2 keys_zone=cache_zone:30m max_size=32g inactive=60m
use_temp_path=off;

upstream cache_server{
server 192.168.184.20:1010 ;
server 192.168.184.20:1011 ;
}

server {
listen 80 ;
server_name cache.codfish.cn ;
if ($request_uri ~ \\.(txt|text)$){
set $cookie_name "no cache";
}
location / {
proxy_cache cache_zone ;
proxy_no_cache $cookie_name ;
proxy_cache_valid 200 5m ;
add_header Nginx-Cache-Status "$upstream_cache_status";
proxy_pass http://cache_server;
}

}

缓存失效降低上游压力

1
2
3
proxy_cache_lock   on | off                     # 阻塞其他相同请求,仅发送一个请求到原始服务器,其他请求使用缓存响应
proxy_cache_timeout # 等待第一个请求响应的超时时间
proxy_cache_lock_age time # 等待周期 按序发送请求

启用陈旧缓存

1
2
3
4
5
6
7
proxy_cache_use_stal error                       # 异常 
timeout # 请求超时
invalid_header # 不可用报头
updating # 正在更新
xx code # 状态码响应
off # 关闭
proxy_cache_background_update on | off # nginx直接进行缓存更新

第三方缓存清除

1
2
proxy_cache_purge zone_name  key ;

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
proxy_cache_path /opt/nginx/cache_temp levels=2:2 keys_zone=cache_zone:30m max_size=32g inactive=60m
use_temp_path=off;

upstream cache_server{
server 192.168.184.20:1010 ;
server 192.168.184.20:1011 ;
}

server {
listen 80 ;
server_name cache.codfish.cn ;
if ($request_uri ~ \\.(txt|text)$){
set $cookie_name "no cache";
}
location ~ /cache_purge(/.*){
proxy_cache_purge cache_zone $host$1;
}

location / {
proxy_cache cache_zone ;
proxy_no_cache $cookie_name ;
proxy_cache_valid 200 5m ;
add_header Nginx-Cache-Status "$upstream_cache_status";
proxy_pass http://cache_server;
}

}

HTTPS

HTTP的局限

1 数据使用明文传输

2 报文的完整性无法验证

3 无法验证通信双方的身份

加密

对称加密

服务端和客户端使用同一把密钥 对数据进行加密/解密操作

  • 优势 协商效率高
  • 劣势 密钥数量太多难以管理/无法进行数据完整性校验/无法传输

非对称加密

服务器和客户端创建一对公钥和私钥。一方使用另一方的公钥对数据进行解密

  • 优势 只需要一个私钥
  • 劣势 公钥是公开的,非对称加密算法加解密过程会耗费一些时间

https加密

  • 使用非对称加密建立连接
  • 使用对称加密加密数据传输
  1. 服务端发送公钥证书给客户端
  2. 客户端创建会话密钥,并使用公钥对密钥进行加密发送到服务端
  3. 服务端收到加密后的密钥使用私钥解密。获取客户端的对称加密密钥
  4. 使用会话加密,发送数据到客户端
  5. 客户端和服务端使用创建的会话密钥进行通信

优化

配置Nginx子进程数与CPU核心数一致 (提高整体的CPU使用率)

配置Nginx子进程与CPU核心绑定(确保子进程只会在一个CPU上被加载调度,减少缓存反复加载过程)

提高子进程优先级,提高被调度器执行的概率

延迟处理新连接 deferred 延迟处理并发连接 直到发起http请求才会触发子进程处理


Nginx 应用
http://gadoid.io/2025/05/19/Nginx-应用/
作者
Codfish
发布于
2025年5月19日
许可协议