首页 > 解决方案 > 如何为 NGINX 负载均衡器设置异常

问题描述

是否可以在 least_conn 模式下配置 NGINX 负载均衡器以使某些路径异常?

我想以这样的方式配置负载均衡器,即单次登录操作所需的所有请求都发送到同一个后端应用程序实例。

我有前端应用程序通过 nginx 负载均衡器访问重复的后端应用程序。所有应用程序都部署在 Tomcat 8.5 上,并且后端实例已配置 Tomcat 之间的会话复制。

我的问题是,当用户使用 OAuth-2.0 授权代码授权方法进行身份验证时,前端应用程序获取授权代码,但由于通过负载均衡器连接到后端,它尝试使用此代码从另一台机器获取令牌,导致 InvalidGrantException。

使用 ip_hash 模式或其变体不能解决此问题,因为通过 VPN 访问应用程序时它是不稳定的。

标签: nginxoauth-2.0requestload-balancing

解决方案


是的,您可以通过声明两个位置并以不同方式对待它们来实现您想要的。请参阅下面的示例并检查此问题,它解释了优先级的工作原理。

http {
  upstream myapp1 {
    least_conn;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
  }

  server {
    listen 80;

    location / {
        proxy_pass http://myapp1;
    }

    location /my-special-path/ {
        proxy_pass http://srv1.example.com;
    }
  }
}

以上是主要基于您希望基于某些路径进行路由的第一个语句的解决方案。如果您的问题更复杂,即这些路径是动态创建的等,您可以分享一个示例以更容易理解您的具体情况。

更新

根据评论。我真的建议您对后端进行故障排除以进行同步。话虽这么说,如果你真的想从你的 nginx 中找到确切问题的解决方案,我会执行以下操作:

  1. 每个响应中,我都会添加一个特定的标头,特定的后端回答了这个请求。add_header X-Upstream $upstream_addr;
  2. 在这个特定的路径上,我将根据该标头的值来处理请求。proxy_pass http://$http_x_upstream;

所以配置看起来像这样:

http {
  ...

  server {
  ...
    location / {
        add_header  X-Upstream  $upstream_addr always;
        proxy_pass http://myapp1;
    }

    location /authorize/ {
        add_header  X-Upstream  $upstream_addr always;
        proxy_pass http://$http_x_upstream;
    }
  }
}

注意:安全。如果您沿着这条路走,请注意您是根据客户端可以操作的值来路由请求。因此,请确保您至少验证了此值。检查此答案以使用 nginx 验证标头。


推荐阅读