Nginx应用
# 反向代理
# 代理介绍
代理是常见设计模式,它是指我们不直接访问目标对象,而是通过代理对象来间接访问目标对象。网络代理是指将网络请求发送给代理服务器,代理服务器再与目标服务器进行通讯。直接来感受如下图所示。
通常代理分为正向代理和反向代理。
正向代理,指的是通过
代理服务器
代理浏览器/客户端
去重定向请求访问到目标服务器
的一种代理服务。反向代理,指的是
浏览器/客户端
并不知道自己要访问具体哪台目标服务器
,只知道去访问代理服务器
,代理服务器
再通过反向代理 +负载均衡
实现请求分发到应用服务器
的一种代理服务。
简单来说是正向代理是客户端代理,反向代理是服务端代理。
# 反向代理配置
nginx反向代理配置核心就是一个指令proxy_pass
。
http{
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://xxx;
#root html/test;
#index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
当我们启动proxy_pass
时,root
和index
字段都会失效。proxy_pass
的地址必须写完整的http://xxx
(目标服务器),不支持https
。
当我们访问nginx服务器时,浏览器地址栏是nginx的服务器的地址,但是网页的内容是代理服务器的内容。
# 拓展
nginx代理,一般称为隧道代理,即所有请求和响应数据都要经过nginx。通常情况下请求数据一般较小,大多数为get和post等方式http请求,而响应数据类型复杂,数据量不稳定。由于nginx的带宽有限的,当响应数据量较大时,可能会产生性能瓶颈。因此我们也可以将响应数据直接放回到客户端,不经过代理服务器,这种方式称为DR代理,实现中间件有LSV。
# 负载均衡
由于代理的每台目标服务器性能不一致,通常会实现负载均衡算法,将网络请求按照一定策略进行分发,保证应用具有高可用和高并发。
nginx负载均衡配置核心就是一个指令upstream
。这个配置就是写一组被代理的服务器地址,然后配置负载均衡算法。
upstream mysvr {
server 192.168.10.121:3333;
server 192.168.10.122:3333;
}
server {
....
location / {
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
}
}
2
3
4
5
6
7
8
9
10
负载均衡算法常用的有轮询
、加权轮询
和ip_hash
算法,默认是轮询
算法。
# 基于轮询负载均衡
轮询原理是每一个请求按时间顺序逐一被分发到不同的应用服务器,如果接收请求的应用服务器挂了,并且请求超过最大失败次数max_fails
(1次),则在失效时间fail_timeout
(10秒)内不会再转发请求到该节点。
upstream weightReverseProxyServer{
server 192.168.0.1:8080 max_fails=1 fail_timeout=10s;
server 192.168.0.2:8080 max_fails=1 fail_timeout=10s;
}
2
3
4
# 基于权重的负载均衡
加权轮询就是在轮询算法基于上新增weight
参数。每一个请求按照权重被分发到不同的应用服务器。同样,如果接收请求的应用服务器挂了,并且请求超过最大失败次数max_fails
(默认1次或可设置N次),则在失效时间fail_timeout
(默认10秒,可设置N秒)内,不会再转发请求到该节。
upstream weightReverseProxyServer{
server 192.168.0.1:8080 weight=10 max_fails=2 fail_timeout=5s;
server 192.168.0.2:8080 weight=5 max_fails=2 fail_timeout=5s;
}
2
3
4
一般使用的是基于权重
的算法,因为现在很多情况下都是集群部署
,而且集群下的各个服务器资源大多都是不均匀的,资源高的则分配权重高一些,资源低的则分配权重低一些,这种情况使用基于权重
的负载均衡算法,可以更高效的利用资源和提高并发处理能力。
# 基于ip_hash的负载均衡
ip_hash原理是每一个请求按用户访问IP的哈希结果分配,如果请求来自同一个用户IP则固定这台IP访问一台服务器,这种策略算法能有效解决动态网络中存在的session
共享问题。
upstream ipHashReverseProxyServer{
ip_hash;
server 192.168.0.1:8080;
server 192.168.0.2:8080;
}
2
3
4
5
# 状态参数
在每个server
后面还可以配置状态参数,用于控制server
的作用,主要介绍两个参数是down
和backup
。
down,表示当前的server暂时不参与负载均衡。
upstream mysvr { server 127.0.0.1:7878; server 192.168.10.121:3333 down; #不会请求到该server }
1
2
3
4backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
upstream mysvr { server 127.0.0.1:7878; server 192.168.10.121:3333 backup; #热备 }
1
2
3
4max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。
# 动静分离
动静分离就是指当用户请求资源时,动态请求分配到tomcat业务服务器,静态资源请求分配到nginx服务器。这样一方面减少tomcat服务器的压力,同时也有效nginx服务器高可用,能在一定程度上提高系统性能。
# 手动配置静态资源
手动配置静态资源就是在location
指令配置资源静态访问URL。
server {
listen 80;
server_name localhost;
location / { # /的优先级比较低,如果下面的location没匹配到,就会走http://xxx这个地址的机器
proxy_pass http://xxx;
}
location /css { # root指的是html,location/css指的是root下的css,所以地址就是html/css
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- 如果请求的资源地址是
location/
,/
的优先级比较低,如果下面的location
没有匹配到,就会走http://xxx
这个地址的机器 - 如果请求的资源地址是
location/css/*
,就会被匹配到nginx的html目录下的css文件夹中(我们把css静态资源放在这个位置)
# 正则表达式配置静态资源
手动配置缺点就是重复写很多location
,我们也可用通过正则表达式来统一写静态资源的匹配路径。
location ~*/(js|css|img){
root html;
index index.html index.htm;
}
2
3
4
# URL重写
rewrite
指令能够实现URL重写,URL重写是指将一个URL请求重写写成另一个URL过程。举个例子来说,在开发中可能经常遇到这样的需求,比如通过浏览器请求的http://localhost:8080/getUser?id=1
,但是需要通过SEO优化等等原因,需要把请求的地址重写为http://localhost:8080/getUser/1
这样的URL,从而符合需求或者更好的被网站阅读。
当遇到这种请求的时候,就需要使用到URL重写或者使用一些网关路由,如SpringCloud的Gateway,Zuul,又或者是Nginx来实现这个功能。
rewrite
指令的语法为:
rewrite <regex> <replacement> [flag];
关键字 正则 替代内容 flagt标记
2
- 正则:正则表达式语句进行规则匹配
- 替代内容:将正则匹配的内容替换成replacement
- flag标记有四种选项
- last:本条规则匹配完成后,继续向下匹配新的1ocation URI规则
- break:本条规则匹配完成即终止,不再匹配后面的任何规则
- redirect:返回302临重定向,游览器地址会显示跳转后的URL地址
- permanent:返回301永久重定向,测览器地址栏会显示跳转后的URL地址
当我们配置一个URL重写如下时,浏览器地址栏访问 xxx/123.html
实际上是访问xxx/index.jsp?pageNum=123
server {
listen 80;
server_name localhost;
location / {
rewrite ^/([0-9]+).html$ /index.jsp?pageNum=$1 break;
proxy_pass http://xxx;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 防盗链
防盗链是指当我们请求到一个页面后,这个页面一般会再去请求其中的静态资源,这时候请求头中,会有一个refer字段,表示当前这个请求的来源,我们可以限制指定来源的请求才返回,否则就不返回,这样可以节省资源。
nginx设置防盗链是指令是valid_referers
,语法格式为:
valid_referers none|server_name
- none:检测地址没有refer,则有效。
- server_name:检测主机地址,refer显示是从这个地址来的,则有效(server_name必须是完整的
http://xxxx
)
例子:这里设置nginx服务器中的img目录下的图片必须refer为http:192.168.174/133才能访问
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://xxx;
}
location /img{
valid_referers http:192.168.174/133;
if ($invalid_referer){#无效的
return 403;#返回状态码403
}
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
如果引用这张图片的页面且refer并没有被设置,图片无法加载出来。
如果直接访问图片地址,因为没有refer字段指向来源,会直接显示Nginx的页面。
若我们需要设置防盗链的图片提示,可将提示图片放在html/img/x.png,访问设置防盗链图片时,就返回这x.png张图。
location /img{
valid_referers http:192.168.174/133;
if ($invalid_referer){#无效的
rewrite ^/ /img/x.png break;
}
root html;
index index.html index.htm;
}
2
3
4
5
6
7
8
# 参考
- https://bbs.huaweicloud.com/blogs/301714
- https://www.runoob.com/w3cnote/nginx-proxy-balancing.html