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] ; }
|
配置示例 :
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; }
|
反向代理设置
创建子系统配置项
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_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 ;
|
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
|
第三方缓存清除
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加密
- 服务端发送公钥证书给客户端
- 客户端创建会话密钥,并使用公钥对密钥进行加密发送到服务端
- 服务端收到加密后的密钥使用私钥解密。获取客户端的对称加密密钥
- 使用会话加密,发送数据到客户端
- 客户端和服务端使用创建的会话密钥进行通信
优化
配置Nginx子进程数与CPU核心数一致 (提高整体的CPU使用率)
配置Nginx子进程与CPU核心绑定(确保子进程只会在一个CPU上被加载调度,减少缓存反复加载过程)
提高子进程优先级,提高被调度器执行的概率
延迟处理新连接 deferred 延迟处理并发连接 直到发起http请求才会触发子进程处理