Nginx 反向代理与负载均衡
知识点:
1. 反向代理基本配置
2. 负载均衡配置与参数解析
3. 负载均衡算法详解
1. 反向代理基本配置
提问:什么是反向代理其与正向代理有什么区别?
正向代理的概念:
正向代理是指客户端与⽬标服务器之间增加⼀个代理服务器,客户端直接访问代理服务器,然后代理服务器向目标服务器转交请求并将获得的内容返回给客户端 。这个过程当中客户端需要知道代理服务器地址,并配置连接。
![](https://img-blog.csdnimg.cn/img_convert/e67d910b5bf375d848675658775df217.png)
反向代理的概念
反向代理是指客户端访问⽬标服务器,在⽬标服务内部有⼀个统⼀接⼊⽹关将请求转发⾄后
端真正处理的服务器并返回结果。这个过程当中客户端不需要知道代理服务器地址,代理对客
户端⽽⾔是透明的。
![](https://img-blog.csdnimg.cn/img_convert/68f4083cbd4e11d61faa4aa400cb2983.png)
反向代理与正向代理的区别
正向代理 | 反向代理 | |
代理服务器位置 | 客户端与服务都能连接的位置 | ⽬标服务器内部 |
主要作⽤
| 屏蔽客户端IP、集中式缓存、解决客户 端不能直连服务端的问题。 | 屏蔽服务端内部实现、负载 均衡、缓存。 |
应⽤场景
| 爬⾍、翻墙、maven 的nexus 服务 | Nginx 、Apache负载均衡应 ⽤ |
Nginx代理基本配置
Nginx 代理只需要配置 location 中配置proxy_pass 属性即可。其指向代理的服务器地址。
# 正向代理到对应服务
location = /index.html {
proxy_pass https://blog.csdn.net/ACTIONTIME/article/details/129486062;
}
# 反向代理至 本机的8010服务
location /luban/ {
proxy_pass http://127.0.0.1:8010;
}
代理相关参数:
proxy_pass # 代理服务
proxy_redirect off; # 是否允许重定向
proxy_set_header Host $host; # 传 header 参数至后端服务
proxy_set_header X-Forwarded-For $remote_addr; # 设置request header 即客户端IP 地址
proxy_connect_timeout 90; # 连接代理服务超时时间
proxy_send_timeout 90; # 请求发送最大时间
proxy_read_timeout 90; # 读取最大时间
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
负载均衡配置与参数解析
通过proxy_pass 可以把请求代理⾄后端服务,但是为了实现更⾼的负载及性能, 我们的后端服务通常是多个, 这个是时候可以通过upstream 模块实现负载均衡。
演示upstream 的实现:
![](https://img-blog.csdnimg.cn/img_convert/ae26a29f2c05a0bf4b314d42fc9f9940.png)
upstream 相关参数:
service 反向服务地址 加端⼝
weight 权重
max_fails 失败多少次 认为主机已挂掉则,踢出
fail_timeout 踢出后重新探测时间
backup 备⽤服务
max_conns 允许最⼤连接数
slow_start 当节点恢复,不⽴即加⼊,⽽是等待 slow_start 后加⼊服务对列。
upstream 负载均衡算法介绍
ll+weight: 轮询加权重 (默认)
ip_hash : 基于Hash 计算 ,⽤于保持session ⼀⾄性
url_hash: 静态资源缓存,节约存储,加快速度(第三⽅)
least_conn :最少链接(第三⽅)
least_time :最⼩的响应时间,计算节点平均响应时间,然后取响应最快的那个,分配更⾼权重(第三⽅)
Nginx ⾼速缓存
1. 缓存案例分析
2. Nginx 静态缓存基本配置
3. 缓存更新
1、案例分析:某电商平台商品详情⻚需要实现 700+ QPS,如何着⼿去做?
1. ⾸先为分析⼀下⼀个商品详情⻚有哪些信息
![](https://img-blog.csdnimg.cn/img_convert/28976b67539f57a0e1cca9b25518f4a9.png)
从中得出商品详情⻚依懒了了如下主要服务:
商品详情⻚HTML⻚⾯渲染
价格服务
促销服务
库存状态/配送⾄服务
⼴告词服务
预售/秒杀服务
评价服务
试⽤服务
推荐服务
商品介绍服务
各品类相关的⼀些特殊服务
解决⽅案:
1. 采⽤Ajax 动态加载 价格、⼴告、库存等服务
2. 采⽤key value 缓存详情⻚主体html。
⽅案架构:
![](https://img-blog.csdnimg.cn/img_convert/3acf1d309f826594b0c85cce931f4db6.png)
问题:
当达到500QPS 的时候很难继续压测上去。
分析原因:⼀个详情⻚html 主体达平均150 kb 那么在500QPS 已接近千M局域⽹宽带极限。必须减少内⽹通信。
基于Nginx 静态缓存的解决⽅案:
![](https://img-blog.csdnimg.cn/img_convert/39da796fe534ee105ab307312b9800bb.png)
Nginx 静态缓存基本配置
⼀、在http元素下添加缓存区声明。
#proxy_cache_path 缓存路径
#levels 缓存层级及目录位数
#keys_zone 缓存区内存大小
#inactive 有效期
#max_size 硬盘大小
proxy_cache_path /data/nginx/cache_luban levels=1:2
keys_zone=cache_luban:500m inactive=20d max_size=1g;
为指定location 设定缓存策略
# 指定缓存区
proxy_cache cache_luban;
#以全路径md5值做做为Key
proxy_cache_key $host$uri$is_args$args;
#对不同的HTTP状态码设置不同的缓存时间
proxy_cache_valid 200 304 12h;
演示缓存⽣效过程
配置声明缓存路径
为location 配置缓存策略
重启nginx(修改了)
查看缓存⽬录⽣成
缓存参数详细说明
![](https://img-blog.csdnimg.cn/img_convert/812832fd15fe443259787e766b6c2c27.png)
缓存的清除:
该功能可以采⽤第三⽅模块 ngx_cache_purge 实现。
为nginx 添加 ngx_cache_purge 模块
#下载ngx_cache_purge 模块包 ,这里nginx 版本为1.6.2 purge 对应2.0版
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
#查看已安装模块
./sbin/nginx -V
#进入nginx安装包目录 重新安装 --add-module为模块解压的全路径
./configure --prefix=/root/svr/nginx --with-http_stub_status_module --
with-http_ssl_module --add-module=/root/svr/nginx/models/ngx_cache_purge-2.0
#重新编译
make
#拷贝 安装目录/objs/nginx 文件用于替换原nginx 文件
#检测查看安装是否成功
nginx -t
清除配置:
![](https://img-blog.csdnimg.cn/img_convert/1f9014e2bae907131c29d55e3c67c032.png)
配置好以后 直接访问 :
# 访问生成缓存文件
# 清除生成的缓存,如果指定缓存不存在 则会报404 错误。
http://www.yingfeng.com/clear/?a=1
Nginx 性能参数调优
worker_processes number;
每个worker进程都是单线程的进程,它们会调⽤各个模块以实现多种多样的功能。如果这些模
块确认不会出现阻塞式的调⽤,那么,有多少CPU内核就应该配置多少个进程;反之,如果有
可能出现阻塞式调⽤,那么需要配置稍多⼀些的worker进程。例如,如果业务⽅⾯会致使⽤户
请求⼤量读取本地磁盘上的静态资源⽂件,⽽且服务器上的内存较⼩,以⾄于⼤部分的请求访
问静态资源⽂件时都必须读取磁盘(磁头的寻址是缓慢的),⽽不是内存中的磁盘缓存,那么
磁盘I/O调⽤可能会阻塞住worker进程少量时间,进⽽导致服务整体性能下降。
每个worker 进程的最⼤连接数
语法:worker_connections number;
默认:worker_connections 1024
worker_cpu_affiffiffinity cpumask[cpumask……]绑定Nginx worker进程到指定的CPU内核
为什么要绑定worker进程到指定的CPU内核呢?假定每⼀个worker进程都是⾮常繁忙的,如
果多个worker进程都在抢同⼀个CPU,那么这就会出现同步问题。反之,如果每⼀个worker
进程都独享⼀个CPU,就在内核的调度策略上实现了完全的并发。
例如,如果有4颗CPU内核,就可以进⾏如下配置:
worker_processes 4;
worker_cpu_affiffiffinity 1000 0100 0010 0001;
注意 worker_cpu_affiffiffinity配置仅对Linux操作系统有效。
Nginx worker 进程优先级设置
语法:worker_priority nice;
默认:worker_priority 0;
优先级由静态优先级和内核根据进程执⾏情况所做的动态调整(⽬前只有±5的调整)共同决
定。nice值是进程的静态优先级,它的取值范围是–20~+19,–20是最⾼优先级,+19是最
低优先级。因此,如果⽤户希望Nginx占有更多的系统资源,那么可以把nice值配置得更⼩⼀
些,但不建议⽐内核进程的nice值(通常为–5)还要⼩
Nginx worker进程可以打开的最⼤句柄描述符个数
语法: worker_rlimit_nofifile limit;
默认:空
更改worker进程的最⼤打开⽂件数限制。如果没设置的话,这个值为操作系统的限制。
设置后你的操作系统和Nginx可以处理⽐“ulimit -a”更多的⽂件,所以把这个值设⾼,
这样nginx就不会有“too many open fifiles”问题了。
是否打开accept锁
语法:accept_mutex[on|off]
默认:accept_mutext on;
accept_mutex是Nginx的负载均衡锁,当某⼀个worker进程建⽴的连接数量达到
worker_connections配置的最⼤连接数的7/8时,会⼤⼤地减⼩该worker进程试图建⽴新TCP
连接的机会,accept锁默认是打开的,如果关闭它,那么建⽴TCP连接的耗时会更短,但
worker进程之间的负载会⾮常不均衡,因此不建议关闭它。
使⽤accept锁后到真正建⽴连接之间的延迟时间
语法:accept_mutex_delay Nms;
默认:accept_mutex_delay 500ms;
在使⽤accept锁后,同⼀时间只有⼀个worker进程能够取到accept锁。这个accept锁不是堵
塞锁,如果取不到会⽴刻返回。如果只有⼀个worker进程试图取锁⽽没有取到,他⾄少要等待
accept_mutex_delay定义的时间才能再次试图取锁。