简体   繁体   English

NGINX中的级联proxy_pass

[英]cascading proxy_pass in NGINX

I'd like to do something like the following: 我想做以下事情:

location ~ ^/(?<upstream>[^/]+)/ {
  rewrite /$upstream/(.*) /api/public/$1  break;

  if ($upstream = "auth") {
    proxy_pass ${AUTH_SERVICE};
  }
  if ($upstream = "todos") {
    proxy_pass ${TODO_SERVICE};
  }
  if ($upstream = "analysis") {
    proxy_pass ${ANALYSIS_SERVICE};
  }
  if ($upstream = "stuff") {
    proxy_pass ${STUFF_SERVICE};
  }
  if ($upstream = "users") {
    proxy_pass ${USERS_SERVICE};
  }
  return 404;
}

The proxy_pass values are built fine with envsubst . proxy_pass值可以通过envsubst很好地envsubst

As an example, requests to public-api.com/auth/* would be mapped to auth-service.com/api/public/* . 例如,对public-api.com/auth/*请求将映射到auth-service.com/api/public/*

When I make the request curl http://localhost:8000/auth/ping , I get a 404, but I can hit auth-service.com/api/public/deep_ping directly. 当我使请求curl http://localhost:8000/auth/ping ,我得到了404,但是我可以直接auth-service.com/api/public/deep_ping

Can anyone spot the bug in the implementation? 谁能发现实现中的错误? Is something like this even advisable? 这样的事情甚至是明智的吗?

I assume the problem are the if statements. 我认为问题是if语句。 If an if matches, the rewrite rule will not be applied. 如果if匹配,则将不应用重写规则。

At least that is my understand after reading the If Is Evil article. 在阅读《 如果是邪恶》一文后,至少我的理解是这样

One alternative to deal with non-trivial logic is to use embedded scripting in Nginx. 处理非平凡逻辑的一种替代方法是在Nginx中使用嵌入式脚本。 For instance, embedded perl or Lua (part of for OpenResty ). 例如, 嵌入式perl或Lua( OpenResty的一部分)。 There is some overhead in setting it up, but as you are then using a normal programming language, implementing complex logic is easier as there are less surprises. 设置它会产生一些开销,但是当您使用一种常规的编程语言时,实现复杂的逻辑会更加容易,因为意外的情况会更少。

Thanks for the link Philipp. 感谢您的链接Philipp。 From reading it, I was able to understand how this works (and is safe): 通过阅读,我能够理解它是如何工作的(并且是安全的):

location ~ /(?<api>[^/]+)/ {
  set $backend 0;

  if ($api = "auth") {
    set $backend ${AUTH_SERVICE};
  }
  if ($api = "todos") {
    set $backend ${TODO_SERVICE};
  }
  if ($api = "analysis") {
    set $backend ${ANALYSIS_SERVICE};
  }
  if ($api = "stuff") {
    set $backend ${STUFF_SERVICE};
  }
  if ($api = "users") {
    set $backend ${USERS_SERVICE};
  }

  if ($backend = 0) {
    return 404;
  }

  rewrite /([^/]+)/(.*) /$2 break;
  proxy_pass $backend;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM