Nginx反向代理的转发规则是怎么处理的?

本文最后更新于:2022年5月4日 晚上

介绍

Nginx是一个高性能的HTTP和反向代理web服务器.因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名

详细

总所周知,Nginx可以通过修改配置文件以开启反向代理。但是具体的转发规则是怎么实现的呢?
Nginx配置文件

1
2
3
4
5
6
7
8
9
10
11
server {

listen 80;

server_name 127.0.0.1;


location / {
proxy_pass http://127.0.0.1:8080;
}
}

以上配置使Nginx监听127.0.0.1的80端口,并将消息转发到 127.0.0.1:8080
如:在浏览器访问http://127.0.0.1/, 则nginx会访问http://127.0.0.1:8080/,并将结果返回
但是在实测中发现,即使你访问的URL为 http://127.0.0.1/articles/, nginx也可以正确的返回结果,可是我们并没有在location里把/articles/给加入,这是为什么?

用Flask写一个web服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from flask import Flask
app = Flask(__name__)

@app.route("/")
def start():
return "im start"

@app.route("/sec/")
def sec():
return "im sec"

@app.route("/sec/haha/")
def haha():
return "im haha"

@app.route("/haha/")
def ha():
return "im ha"

if __name__ == "__main__":
app.run("127.0.0.1", 8080, debug=True)

在这段代码里,我们设置了三个路由。在原先的Nginx配置下, 访问对应的URL可以得到对应的内容

  1. “/“, 返回”im start”
  2. “/sec/“, 返回”im sec”
  3. “/sec/haha/“, 返回”im haha”
  4. “/haha/“ 返回”im ha”

此时我们修改一下nginx的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {

listen 80;

server_name 127.0.0.1;


location / {
proxy_pass http://127.0.0.1:8080;
}

location /sec {
proxy_pass http://127.0.0.1:8080;
}
}

在新的nginx配置中,我们添加了/sec这个路由。此时访问上面的4个URL会发生什么?

  1. “/“, 返回”im start”
  2. “/sec/“, 返回”im start
  3. “/sec/haha/“, 返回”im ha
  4. “/haha/“ 返回”im ha”

可以看到,有两条URL的返回内容变了
因此可以判断,在nginx中的location是根据最长匹配到的URL进行分配的。当我们访问 “/sec” 这样的URL时,由于它的长度比 “/“长,因此nginx匹配到了第二个location所对应的服务器。并且将匹配完成后剩余的URL部分重新拼接

如:当访问http://127.0.0.1/sec/haha 的时候,由于”/sec”部分已经被匹配,因此把剩余的部分 “/haha” 拼接到 “http://127.0.0.1:8080" 后,变成了 “http://127.0.0.1:8080/haha", 这才造成了我们访问以上URL时返回不同结果的原因


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!