Nginx的location与proxy_pass配置
在使用Nginx做反向代理时,常用location
和proxy_pass
进行配置。例如:
假设Nginx运行在localhost:8080
上,那么当访问http://localhost:8080/proxy
时,实际访问的是http://localhost:9000
上运行的服务。
配置效果表格
不过,更加详细地,访问路径(代理前)与实际路径(代理后)是如何对应的呢?这根据location
后面有没有/
,以及proxy_pass
的IP、端口号后面有没有/
或更多内容,实际情况是不一样的。如下表所示:
编号 | location | proxy_pass | 访问路径(代理前) | 实际路径(代理后) |
---|---|---|---|---|
1 | /proxy | http://localhost:9000 | /proxy/service | /proxy/service |
2 | /proxy | http://localhost:9000/ | /proxy/service | //service |
3 | /proxy | http://localhost:9000/app | /proxy/service | /app/service |
4 | /proxy | http://localhost:9000/app/ | /proxy/service | /app//service |
5 | /proxy/ | http://localhost:9000 | /proxy/service | /proxy/service |
6 | /proxy/ | http://localhost:9000/ | /proxy/service | /service |
7 | /proxy/ | http://localhost:9000/app | /proxy/service | /appservice |
8 | /proxy/ | http://localhost:9000/app/ | /proxy/service | /app/service |
9 | / | http://localhost:9000 | /proxy/service | /proxy/service |
10 | / | http://localhost:9000/ | /proxy/service | /proxy/service |
11 | / | http://localhost:9000/app | /proxy/service | /appproxy/service |
12 | / | http://localhost:9000/app/ | /proxy/service | /app/proxy/service |
根据实际路径的格式正确性,可以认为其中第2、4、7、11种配置是“不应该”的(删除线)。具体应该使用哪一种配置,显然要根据业务场景而定。(我个人更加偏好第5种配置。)
路径处理规律
乍一看情况比较复杂,但实际上有简单的规律可循,只需要区分两种情况:
- 情况A:
proxy_pass
的URL当中只有IP、端口号,后面什么都没有,就连/
都没有。此时,访问的路径将被原封不动地拼接到IP、端口号的后面。(上表中的第1、5、9种配置都是如此。) - 情况B:
proxy_pass
的URL除了IP、端口号之外,后面有一个/
或者更多内容。此时,访问的路径将去掉location
的前缀部分,并将剩余的路径拼接到proxy_pass
的后面。(上表中的第2、3、4、6、7、8、10、11、12种配置都是如此。)
例如上表第1种配置,proxy_pass
为http://localhost:9000
,后面没有/
或更多内容,属于情况A。此时直接拼上访问路径/proxy/service
即可得到实际路径http://localhost:9000/proxy/service
。
又如上表第3种配置,proxy_pass
为http://localhost:9000/app
,后面多了/app
的部分,属于情况B。此时将访问路径/proxy/service
的开头裁剪掉location
的/proxy
,只得到剩余的/service
部分,将其拼接到proxy_pass
后面。即:
这样就清楚了很多。
本文的
location
配置没有使用修饰符(location modifier),只是简单的路径前缀匹配而已。相关配置专题请参考另一篇文章(TODO)。