我正在尝试使用有趣的Apache mod_rewrite设置来转换反向代理以使用Nginx(由于外部问题,我们正在从Apache转移到Nginx,除了这部分,大多数一切都正常).
我的原始设置是读取HTTP cookie(由某个应用程序设置),并根据其值,将反向代理指向不同的后端.它是这样的:
RewriteCond %{HTTP_COOKIE} proxy-target-A RewriteRule ^/original-request/ http://backend-a/some-application [P,QSA] RewriteCond %{HTTP_COOKIE} proxy-target-B RewriteRule ^/original-request http://backend-b/another-application [P,QSA] RewriteRule ^/original-request http://primary-backend/original-application [P,QSA]
我正在尝试使用Nginx实现相同的功能,我的初始配置是这样的(其中“proxy_override”是cookie的名称):
location /original-request { if ($cookie_proxy_override = "proxy-target-A") { rewrite . http://backend-a/some-application; break; } if ($cookie_proxy_override = "proxy-target-B") { rewrite . http://backend-b/another-application; break; } proxy_pass http://primary-backend/original-application; }
但事实并非如此.我试图看看Nginx是否可以通过编写主代理来重定向到基于${cookie_proxy_override}的内容来读取我的cookie,我可以看到它读取的内容很好,但ifs似乎总是失败.
根据Rikih的回答,我的下一次尝试是这样的:
location /original-request { if ($http_cookie ~ "proxy-target-A") { rewrite . http://backend-a/some-application; break; } if ($http_cookie ~ "proxy-target-B") { rewrite . http://backend-b/another-application; break; } proxy_pass http://primary-backend/original-application; }
现在我可以看到if块被激活,但不是代理请求(就像我认为的那样),它返回302重定向到指定的URL – 这不是我想要做的:我需要服务器透明地将请求中继到后端并将响应传递给原始客户端.
我究竟做错了什么?
解决方法
与
this answer类似.Nginx对这类问题的惯用方法是通过地图.
基本上,您在http部分中定义一个地图
map $cookie_proxy_override $my_upstream { default default-server-or-upstream; ~^(?P<name>[\w-]+) $name; }
然后你只需在位置部分使用$my_upstream:
location /original-request { proxy_pass http://$my_upstream$uri; }
Nginx懒惰地评估地图变量,只有一次(每个请求)以及何时使用它们.