Nginx的location与proxy_pass配置
在使用Nginx做反向代理时,常用location和proxy_pass进行配置。例如:
http {    server {        location /proxy {            proxy_pass http://localhost:9000 ;        }    }}假设Nginx运行在localhost:8080上,那么当访问http://localhost:8080/proxy时,实际访问的是http://localhost:9000上运行的服务。
本文的
location配置均没有使用修饰符(location modifier),只是简单的路径前缀匹配而已。
配置效果表格
Section titled “配置效果表格”不过,更加详细地,访问路径(代理前)与实际路径(代理后)是如何对应的呢?这根据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种配置。)
路径处理规律
Section titled “路径处理规律”乍一看情况比较复杂,但实际上有简单的规律可循,只需要区分两种情况:
- 情况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后面。即:
Step 1: "/proxy/service" - "/proxy" = "/service"Step 2: "http://localhost:9000/app" + "/service" = "http://localhost:9000/app/service"这样就清楚了很多。