在 Nginx 中为 location 下的多个代理端点提供服务

在 Nginx 中为 location 下的多个代理端点提供服务

我有几个 API 端点,我想从 的单个位置提供服务,/api子路径指向不同的端点。具体来说,我希望 webdis 在 可用/api,专有 API 在 可用/api/mypath

我并不担心与 webdis API 发生冲突,因为我使用的子路径不太可能与 redis 命令名称发生冲突,并且可以完全控制 API 的设计以避免冲突。

这是我一直在攻击的测试服务器的配置文件:

server {
  listen 80;
  server_name localhost;
  server_name 192.168.3.90;
  server_name 127.0.0.1;

  location / {
    root /home/me/src/phoenix/ui;
    index index.html;
  }

  # temporary hardcoded workaround
  location = /api/mypath/about {
    proxy_pass http://localhost:3936/v1/about;
  }

  location /api {
    rewrite ^/api/(.*)$ /$1 break;
    proxy_pass http://localhost:7379/;
  }

  # tried this but it gives "not found" error
  #location ^~ /api/mypath/ {
  #  rewrite ^/api/mypath/(.*)$ /$1 break;
  #  proxy_pass http://localhost:3936/v1/;
  #}
  #
  #location ^~ /api {
  #  rewrite ^/api/(.*)$ /$1 break;
  #  proxy_pass http://localhost:7379/;
  #}
}

我怎样才能改变我的解决方法,以便任何请求都/api/mypath/*将发送到端口 3936 的端点,而其他所有请求都将发送到端口 7379?

答案1

您不需要为此重写。

server {
  ...

  location ^~ /api/ {
    proxy_pass http://localhost:7379/;
  }
  location ^~ /api/mypath/ {
    proxy_pass http://localhost:3936/v1/;
  }
}

根据nginx 文档

位置既可以由前缀字符串定义,也可以由正则表达式定义。正则表达式使用前面的~*修饰符(用于不区分大小写的匹配)或~修饰符(用于区分大小写的匹配)指定。要查找与给定请求匹配的位置,nginx 首先检查使用前缀字符串定义的位置(前缀位置)。在其中,选择并记住具有最长匹配前缀的位置。然后按照正则表达式在配置文件中出现的顺序检查正则表达式。正则表达式的搜索在第一次匹配时终止,并使用相应的配置。如果未找到与正则表达式匹配的项,则使用先前记住的前缀位置的配置。

如果最长匹配的前缀位置有^~修饰符,则不检查正则表达式。

因此,任何以开头的请求/api/mypath/将始终由第二个块处理,因为这是最长匹配前缀位置。

/api/任何以 开头且不紧跟 的请求mypath/将始终由第一个块处理,因为第二个块不匹配,因此第一个块是最长匹配前缀位置。

答案2

好的,我明白了,我以为“未找到”错误来自 nginx,但实际上它来自我的 API。如果有人感兴趣的话,这是我的解决方案:

server {
  listen 80;
  server_name localhost;
  server_name 192.168.3.90;
  server_name 127.0.0.1;

  location / {
    root /home/me/src/phoenix/ui;
    index index.html;
  }

  # automatically go to v1 of the (grape) API
  location ^~ /api/mypath/ {
    rewrite ^/api/mypath/(.*)$ /v1/$1 break;
    proxy_pass http://localhost:3936/;
  }

  location ^~ /api {
    rewrite ^/api/(.*)$ /$1 break;
    proxy_pass http://localhost:7379/;
  }
}

相关内容