版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。

需求描述

  • 测试环境公网资源有限,仅能增加一个二级域名
  • 该二级域名配置的功能涉及3方面的资源,分布在不同的服务器
  • 通过域名能正常访问对应的资源
序号URL后端服务器后端服务器2备注
1demos.lfang123.com

http://192.168.113.101:32221


前端应用
2demos.lfang123.com/backend/http://192.168.192.85:9080
后端 API 应用
3demos.lfang123.com/erp/http://192.168.113.101:32221微服务中台服务器展示前端页面的自定义框架内容

问题描述

原因分析

这个问题通常是因为 proxy_pass 指令在处理请求时没有将原始的查询参数(query string)传递给目标服务器。在默认情况下,Nginx 会尝试重写请求的 URI,但这样做可能会导致查询参数的丢失。

解决方案

代码块
languagetext
   location ~ /backend/ {
        rewrite ^/backend(/.*)$ $1 break;
        proxy_pass http://192.168.192.85:9080;
        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  /erp {
        proxy_pass http://192.168.113.101:32221;
        proxy_set_header   Host    $host;
        proxy_set_header   X-Real-IP   $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
    }                         

参考

基础配置

假设我们有一个基础的 Nginx 反向代理配置,如下:

代码块
languagetext
location /api/ {
  proxy_pass  https://10.76.77.27:443;
}

当通过 Nginx 发送一个带参数的 GET 请求时,例如 https://yourdomain.com/api/?key=value,反向代理后的请求可能会丢失这个 key=value 参数

方法一:保留原始请求 URI

要解决这个问题,最简单的方式是在 proxy_pass 指令后面加上一个 /,这样 Nginx 会将整个请求 URI(包括查询参数)传递给被代理的服务器。

代码块
languagetext
 location /api/ {
  proxy_pass  https://10.76.77.27:443/;
}

方法二:使用 proxy_set_header

除了上面的方法,我们还可以通过设置 proxy_set_header 来手动传递 Host 和 Request URI。

代码块
location /api/ {
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_pass https://10.76.77.27:443;
}

方法三:使用 rewrite

我们也可以使用 rewrite 指令来重新定义请求 URI,这样做更加灵活,但也更复杂。

代码块
location /api/ {
  rewrite ^/api(/.*)$ $1 break;
  proxy_pass https://10.76.77.27:443;
}

这里,rewrite 指令将 URI 中的 /api 部分去掉,并将剩下的部分(包括查询参数)传递给 proxy_pass。

Nginx 子域名 访问 subdomain

代码块
languagetext
server {
    listen 443 ssl;
    server_name ~^(?<subdomain>.+).test.net$;
    set $subdomain_root /www/test.net/$subdomain;

    if (!-d $subdomain_root) {
      return 404;
    }

    root /www/test.net/$subdomain;
    index index.php index.html;
}

根据请求头分发

需求如下:

loc: /aa ==> http://127.0.0.1:28080/aa

pro: /aa ==> http://127.0.0.1:8011/api/

其它: /aa ==> http://127.0.0.1:8022/api/

解决方式

代码块
languagenginx
location /aa {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-real-ip $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    if ($http_environment_name = "loc" ) {
      proxy_pass http://127.0.0.1:28080;
      break;
    }
   if ($http_environment_name = "pro" ) {
      rewrite ^/aa /(.*)$ /api/$1 break;
      proxy_pass http://127.0.0.1:8011;
      break;
    }
    proxy_pass http://127.0.0.1:8022/api/;
}

测试

代码块
languageshell
curl -H "environment-name: " http://127.0.0.1:8089/aa
curl -H "environment-name: ssss" http://127.0.0.1:8089/aa
curl -H "environment-name: loc" http://127.0.0.1:8089/aa
curl -H "environment-name: pro" http://127.0.0.1:8089/aa

在 Nginx 中,$http_environment_name 是一个变量,用于获取 HTTP 请求头中名为 Environment-Name 的值。这个变量可以在 Nginx 配置文件中用于条件判断、日志记录或其他配置目的。

环境区分:可以用来区分不同的环境(如开发、测试、生产)进行不同的配置。例如,可以根据环境名称选择不同的后端服务或配置。
日志记录:在访问日志中记录请求的环境信息,以便于后续的分析和监控。
条件判断:在 Nginx 的 if 语句中使用,允许根据请求的环境动态改变配置。

目录