简介

正向代理

如果把局域网外的 Internet 想象成一个巨大的资源库,则局域网中的客户端要访问 Internet,则需要通过代理服务器来访问,这种代理服务就称为正向代理。

正向代理原理

反向代理

客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器 IP 地址。

反向代理原理

正向代理和反向代理的区别:

​ 如果我们自己调用本地接口,就是正向代理。

​ 如果是调用服务器接口,我们用户无感知,就是反向代理。

location配置

Nginx的反向代理主要通过location来配置,来看一个简单的例子

1
2
3
4
5
6
server {
listen 80; #监听80端口
location /random {
proxy_pass http://127.0.0.1:8098/;#代理到8098端口
}
}

定义一个server模块,表示一个虚拟主机

location 匹配顺序

1、location 匹配格式规则前缀有如下几种:

  • = 开头:表示精确匹配
  • ^~ 开头:注意这不是一个正则表达式,它的目的是优于正则表达式的匹配;如果该 location 是最佳匹配,则不再进行正则表达式检测。
  • ~ 开头:表示区分大小写的正则匹配;
  • ~* 开头:表示不区分大小写的正则匹配
  • **!~ && !~***:表示区分大小写不匹配的正则和不区分大小写的不匹配的正则

2、location 如果不带前缀就是普通字符串匹配,比如:

  • /uri/ 普通字符串匹配
  • / 绝对路径根目录匹配,如果没有其它匹配,任何请求都会匹配到

3、匹配的搜索顺序优先级如下(从上到下优先级依次递减):

  • 首先匹配 =
  • 其次匹配 ^~
  • 再其次按照配置文件的顺序进行正则匹配
  • 最后是交给 / 进行通用匹配

注意:

当有匹配成功时,立刻停止匹配,按照当前匹配规则处理请求

优先搜索并不意味着优先命中!

字符串匹配优先搜索,但是只是记录下最长的匹配 ( 如果 ^~ 是最长的匹配,则会直接命中,停止搜索正则 ),然后继续搜索正则匹配,如果有正则匹配,则命中正则匹配,如果没有正则匹配,则命中最长的字符串匹配。

匹配模式及顺序举例

  • location = /uri    = 开头表示精确匹配,只有完全匹配上才能生效。
  • location ^~ /uri   ^~ 开头对 URL 路径进行前缀匹配,并且在正则之前。
  • location ~ pattern  ~ 开头表示区分大小写的正则匹配。
  • location ~* pattern  ~* 开头表示不区分大小写的正则匹配。
  • location /uri 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后,如果没有正则命中,命中最长的规则。
  • location /   通用匹配,任何未匹配到其它 location 的请求都会匹配到,相当于 switch 中的 default

location / 匹配规则

1、没有“**/”结尾时,location/random** 可以匹配 /random11 请求,也可以匹配 /random/11

1
2
3
4
5
6
server {
listen 80; #监听80端口
location /random {
proxy_pass http://127.0.0.1:8098/;#代理到8098端口
}
}

2、而有“**/”结尾时,location/random/** 不能匹配 /random11 请求,只能匹配 /random/11 这样的请求

1
2
3
4
5
6
server {
listen 80; #监听80端口
location /random/ {
proxy_pass http://127.0.0.1:8098/;#代理到8098端口
}
}

proxy_pass 代理规则

1、没有“**/”结尾时,Nginx** 则会把匹配的路径部分加入代理 uri,例如:

访问http://ip:80/random/getName,最终代理到**URL**是 http://127.0.0.1:8098/random/getName

1
2
3
4
5
6
server {
listen 80; #监听80端口
location /random {
proxy_pass http://127.0.0.1:8098;#代理到8098端口
}
}

2、而有“**/”结尾时,相当于是绝对路径**,则 Nginx不会把 location 中匹配的路径部分加入代理 uri,例如:

访问http://ip:80/random/getName,最终代理到**URL**是 http://127.0.0.1:8098/getName

1
2
3
4
5
6
server {
listen 80; #监听80端口
location /random {
proxy_pass http://127.0.0.1:8098/;#代理到8098端口
}
}

参考文章

https://www.hangge.com/blog/cache/detail_2979.html

https://developer.aliyun.com/article/506996