proxy_pass 指令在 Nginx 中是实现反向代理和负载均衡的重要指令。
一. 反向代理
在反向代理的场景下,proxy_pass 指令用于将接收到的请求转发给另一个后端服务器。后端服务器地址可以是 IP 地址加端口、域名加端口、或者一个完整的 URL。
注意事项
proxy_pass 后面的 URL 末尾是否存在 / 的处理逻辑不同。如果在 proxy_pass 后面的 URL 加 /,表示绝对根路径;如果没有 /,表示相对路径,可能会把匹配的路径部分也给代理走。
示例如下:
情况一
nginx
location /api/ {
proxy_pass http://localhost:8080/;
}
location /V1/ {
proxy_pass http://localhost:8080/api/;
}
对于访问 http://example.com/api/test,Nginx 会将其转发到 http://localhost:8080/test。
对于访问 http://example.com/V1/data,Nginx 会将其转发到 http://localhost:8080/api/data。
注意:如果 proxy_pass 指令包含了一个 URI 路径(/api/),Nginx 会将这个路径与原始请求 URI 中匹配 location 块后剩余的部分(data)进行拼接。在拼接时,,Nginx 会确保路径的拼接是正确的,并且没有不必要的双斜杠(//)。
情况二
nginx
location /api/ {
proxy_pass http://localhost:8080;
}
对于访问 http://example.com/api/test,Nginx 会将其转发到 http://localhost:8080/api/test。
情况三
nginx
location /V1 {
proxy_pass http://localhost:8080/api;
}
对于访问 http://example.com/V1/data,Nginx 会将其转发到 http://localhost:8080/api/data。
注意:确保 location 块和 proxy_pass 指令的路径部分要么都加斜杠(/),要么都不加斜杠。
情况四
nginx
location ~ /api/ {
proxy_pass http://localhost:8080; # 不可以写成 8080/...
}
对于访问 http://example.com/api/test,Nginx 会将其转发到 http://localhost:8080/test。
注意:当 location 使用正则表达式来匹配请求的 URI 时,proxy_pass 应该只包含主机名和端口号,而不应该包含任何 URI 路径。
二. 负载均衡
在负载均衡的场景下,proxy_pass 指令与 upstream 模块一起使用,用于将请求分发到多个后端服务器中的一个。
nginx
upstream backend-servers {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
server {
listen 80;
server_name www.example.com;
location /api/ {
proxy_pass http://backend-servers;
}
}
负载均衡默认使用的是轮询算法,按照时间先后来分发请求,第一个 request 走 srv1.example.com,第二个 request 走 srv2.example.com ... 以此类推。