在Nginx中的位置下服务多个代理端点


14

我有几个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?


你是什么意思tried this to no avail?启用该位置指令后会发生什么?连接超时?位置不符?
masegaloeh 2014年

谢谢您的提示,它给出了一个未找到的错误,在进一步调查中,似乎该错误来自我的API,因此可以正常工作!:D但是重写规则显然不是因为我必须将v1添加到URL(localhost / api / mypath / v1 / about)... :(
hamstar 2014年

Answers:


24

您不需要为此重写。

server {
  ...

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

根据nginx文档

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

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

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

因为第二个块不匹配,所以所有以第一个块/api/不立即开始的请求mypath/都将始终由第一个块服务,因此使第一个块成为最长匹配前缀位置。


2
如果你看一下位置修饰符(=~*~^~),它可能似乎违反直觉的认为^~不包括正则表达式(因为~表示正则表达式匹配)......但是,如果你还记得,^一个正则表达式字符类中(例如[^a-z],通过则无效即类(例如,示例意味着( z 以外的任何字符);类似地,^~否定所有潜在的正则表达式位置块。)
Doktor J

6

OK弄清楚了,我以为“找不到”错误来自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/;
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.