Nginx location 和 proxy_pass 配置详解【转】

proxy_pass 是 Nginx 中一个非常重要的指令,用于将请求代理到后端服务器。本文将详细介绍 proxy_pass 的基本用法、配置示例以及一些高级用法。

1. 基本概念
1.1 proxy_pass 概述
proxy_pass 指令用于将请求转发到后端服务器。它可以用于 HTTP 和 Stream 模块,分别处理 HTTP 请求和 TCP/UDP 流量。

1.2 语法

proxy_pass URL;

URL:后端服务器的地址,可以是 HTTP/HTTPS 地址或 TCP/UDP 地址。

1.3 使用场景
HTTP 代理:将 HTTP 请求转发到后端服务器。
Stream 代理:将 TCP/UDP 流量转发到后端服务器。

2. 基本用法
2.1 HTTP 代理
2.1.1 基本示例

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend_server;
    }
}

在这个示例中,所有访问 example.com 的请求都会被转发到 backend_server。

 

2.1.2 绝对根路径 vs 相对路径
绝对根路径:在 proxy_pass 后面的 URL 以斜杠 / 结束,表示绝对根路径。

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

例如,访问 http://example.com/proxy/test.html 会被转发到 http://127.0.0.1/test.html。

相对路径:在 proxy_pass 后面的 URL 不以斜杠 / 结束,表示相对路径。

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

例如,访问 http://example.com/proxy/test.html 会被转发到 http://127.0.0.1/proxy/test.html。

 

2.2 Stream 代理

stream {
    upstream backend {
        server 127.0.0.1:8080;
    }

    server {
        listen 12345;
        proxy_pass backend;
    }
}

在这个示例中,所有连接到 12345 端口的 TCP 流量都会被转发到 127.0.0.1:8080。

 

3. 高级用法
3.1 正则匹配
当 location 使用正则表达式时,proxy_pass 不能包含 URI 部分。

location ~ /testc {
    proxy_pass http://127.0.0.1:8801;
}

如果包含 URI 部分,会导致配置文件解析错误:

location ~ /testd {
    proxy_pass http://127.0.0.1:8801/;  # 错误
}

 

3.2 变量使用
可以使用变量来动态生成转发地址。

location /novel/ {
    proxy_pass http://book-server/books$request_uri;
}

例如,访问 http://example.com/novel/three-body.html?page=3 会被转发到 http://book-server/books/novel/three-body.html?page=3。

 

3.3 重定向
Nginx 会在某些情况下自动进行 301 重定向,例如当请求的 URI 没有以斜杠 / 结束,但 Nginx 认为这是一个目录时。

location /films/nature/ {
    proxy_pass http://film-server;
}

如果访问 http://example.com/films/nature,Nginx 会返回 301 重定向到 http://example.com/films/nature/。

 

3.4 精确匹配
可以使用精确匹配来避免 301 重定向。

location /films/nature/ {
    proxy_pass http://film-server;
}

location = /films/nature {
    proxy_pass http://film-server;
}

 

3.5 if 语句
在 location 中使用 if 语句时,proxy_pass 不能包含 URI 部分。

location /google {
    if ($geoip_country_code ~ (RU|CN)) {
        proxy_pass http://www.google.hk;
    }
}

 


3.6 limit_except
在 limit_except 中使用 proxy_pass 时,不能包含 URI 部分。

location /yongfu/ {
    proxy_pass http://unix:/tmp/backend.socket:/uri/;

    limit_except PUT DELETE {
        proxy_pass http://127.0.0.1:9080;
    }
}

 

4. 实际案例
4.1 转发到多个后端服务器

upstream backend_servers {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend_servers;
    }
}

 

4.2 转发到不同路径

server {
    listen 80;
    server_name example.com;

    location /api/ {
        proxy_pass http://api_server/;
    }

    location /static/ {
        proxy_pass http://static_server/;
    }
}

 

4.3 转发到 Unix Domain Socket

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://unix:/tmp/backend.socket:/uri/;
    }
}

 

————————————————

 

概述
Nginx 配置中 location 和 proxy_pass 指令的不同组合方式及其对请求转发路径的影响。

配置效果


1. location 和 proxy_pass 都带斜杠 /

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

访问地址:www.hw.com/api/upload
转发地址:http://127.0.0.1:8080/upload
转发地址不带 location 匹配目录 /api/

 

2. location 不带斜杠,proxy_pass 带斜杠 /

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

访问地址:www.hw.com/api/upload
转发地址:http://127.0.0.1:8080//upload
转发地址会多带 /

 

3. location 带斜杠,proxy_pass 不带斜杠

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

访问地址:www.hw.com/api/upload
转发地址:http://127.0.0.1:8080/api/upload
转发地址会带 location 匹配目录 /api/

 

4. location 和 proxy_pass 都不带斜杠

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

访问地址:www.hw.com/api/upload
转发地址:http://127.0.0.1:8080/api/upload
转发地址会带 location 匹配目录 /api/

 

5. location 和 proxy_pass 都带斜杠 /,但 proxy_pass 带地址

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

访问地址:www.hw.com/api/upload
转发地址:http://127.0.0.1:8080/server/upload
转发地址不带 location 匹配目录 /api/

 

6. location 不带斜杠,proxy_pass 带斜杠 /,但 proxy_pass 带地址

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

访问地址:www.hw.com/api/upload
转发地址:http://127.0.0.1:8080/server//upload
转发地址不带 location 匹配目录 /api/ ,会多带 /

 

7. location 带斜杠,proxy_pass 不带斜杠,但 proxy_pass 带地址

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

访问地址:www.hw.com/api/upload
转发地址:http://127.0.0.1:8080/serverupload
转发地址不带 location 匹配目录 /api/ 直接进行了替换

 

8. location 和 proxy_pass 都不带斜杠,但 proxy_pass 带地址

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

访问地址:www.hw.com/api/upload
转发地址:http://127.0.0.1:8080/server/upload
转发地址不带 location 匹配目录 /api

 

总结

当 proxy_pass 代理地址端口后有目录(包括 /),转发后地址为:代理地址 + 访问 URL 目录部分去除 location 匹配目录。
当 proxy_pass 代理地址端口后无任何内容,转发后地址为:代理地址 + 访问 URL 目录部分(包括 location 地址)。
场景示例

upstream backend_name_hw {
  server 10.10.10.10:32323 max_fails=2 fail_timeout=2;
}

server {
    listen      80;
    server_name hw.test.com;

    client_max_body_size 1024m;
    client_body_timeout 12;
    client_header_timeout 12;
    keepalive_timeout 15;
    send_timeout 10;

    location / {
      proxy_pass http://backend_name_hw;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    
    location /hello {
      proxy_pass http://backend_name_hw/hello;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

 

 

    location /hw/ {
        proxy_pass http://hw-nginx/index.html;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

 

 

    location /hwhw/  {
        proxy_pass http://hw-nginx/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

 

 

    location /hw/hi/ {
        proxy_pass http://hw-nginx/hello/index.html;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

 

 

    location /hello/index.html {
        proxy_pass http://hw-nginx;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

 

 

 

————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_74823452/article/details/145867212

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_74824661/article/details/146106777

 

posted @ 2025-04-29 09:31  paul_hch  阅读(2301)  评论(0)    收藏  举报