使用 Header 而不是 Cookie 来定位特定的 Azure Web 应用程序实例

Target specific Azure Web App Instance with Header instead of a Cookie

我有一个架构,其中有多个实例,但我想最大化 缓存命中率

用户是按组定义的,我想确保属于同一组的所有用户尽可能访问同一服务器

该应用程序是完全无状态的,但是让来自同一组的用户访问同一台服务器将显着提高所有实例的性能和内存负载。

加载主页时,我已经知道在 XHR 调用中我想将该用户发送到哪个服务器。

使用 ARRAffinity cookie 不是很好 在这种情况下几乎不可能(跨域,必须先调用服务器等),我强烈希望通过自定义 header.

我自己发送提示

我正在尝试通过删除 cookie 和分配它们来手动执行一些解决方法,但感觉很麻烦 而且我还没有完全使用它。 而且它不适用于 XHR 调用。

问题:

是否可以通过 header、url 或域而不是 cookie[= 指向特定实例46=]?

备注

  • 在这种情况下,分布式缓存对我不起作用。我需要没有额外网络跃点和 serialization/deserialization.
  • 的内存缓存性能
  • 这似乎可以通过应用程序网关实现,但它似乎需要大量额外的基础设施和移动部件,而我所有的问题都可以通过发送 "对" header.
  • 我可以通过复制整个网络应用程序并分配不同的主机名来解决这个问题。此外,这感觉就像添加了很多可能会损坏的额外移动部件。维护也会更难、更混乱,我失去了自动缩放等。
  • 也许这可以通过 Kubenetes/Docker Swarm 类型的架构轻松解决(没有经验),但由于这是一个大型遗留项目,而且我有一个非常严格的截止日期,所以我对制作如此戏剧性的作品非常谨慎最后一分钟切换。

如果我理解正确,您想通过客户端应用程序设置自定义 header 并基于该代理通过连接到其他后端服务器。

我喜欢为此使用 HAProxy,您也可以查看 Nginx。 您可以从发行版的包管理器在 linux 上安装 HAProxy,或者您可以使用可用的 HAProxy docker 容器。 在 ArchLinux 上安装它的示例:

sudo pacman -S haproxy 
sudo systemctl start haproxy

安装后,您可以找到 haproxy.cfg 配置文件所在的位置,然后复制我在下面发布的 haproxy.cfg 配置片段,而不是现有的默认配置。

在我的例子中 haproxy.cfg 在 /etc/haproxy/haproxy.cfg

为了在 HAProxy 中实现您想要的,您可以将所有客户端设置为与这个主 HAProxy 服务器通信,然后它将根据自定义 header 的值将连接转发到您拥有的不同后端服务器您可以设置客户端,例如 "x-mycustom-header: Server-one"。作为奖励,如果需要,您还可以在 HAProxy 上启用粘性会话,但这并不是实现您想要的功能的强制性要求。

这是 HAProxy 配置文件 (haproxy.cfg) 的简单示例设置,只有 2 个后端服务器,但您可以添加更多。

这里的逻辑是,所有客户端都会向侦听端口 80 的 HAProxy 服务器发出 http 请求,然后 HAProxy 会检查名为“x-mycustom-header”的自定义 header 的值,添加的客户端并根据该值,它将客户端转发到 backend_server_onebackend_server_two.

出于测试目的,HAProxy 和两个后端都在同一个盒子上,但侦听不同的端口。 HAProxy 在端口 80 上,服务器 1 在 127.0.0.1:3000 上,服务器 2 在 127.0.0.1:4000 上。

 cat haproxy.cfg
#---------------------------------------------------------------------
# Example configuration.  See the full configuration manual online.
#
#   http://www.haproxy.org/download/1.7/doc/configuration.txt
#
#---------------------------------------------------------------------

global
    maxconn     20000
    log         127.0.0.1 local0
    user        haproxy
    chroot      /usr/share/haproxy
    pidfile     /run/haproxy.pid
    daemon

frontend  main
    bind :80
    mode                 http
    log                  global
    option               httplog
    option               dontlognull
    option               http_proxy
    option forwardfor    except 127.0.0.0/8
    maxconn              8000
    timeout              client  30s
    use_backend backend_server_one if { req.hdr(x-mycustom-header) server-one }
    use_backend backend_server_two if { req.hdr(x-mycustom-header) server-two }
    default_backend      backend_server_one #when the header is something else default to the first backend

backend backend_server_one
    mode        http
    balance     roundrobin
    timeout     connect 5s
    timeout     server  5s
    server      static 127.0.0.1:3000 #change this ip to your 1st backend ip address

backend backend_server_two
    mode        http
    balance     roundrobin
    timeout     connect 5s
    timeout     server  30s
    server      static 127.0.0.1:4000 #change this ip to your 2nd backend ip address

要测试这是否有效,您可以打开两个 netcat 侦听器,一个在端口 3000 上,另一个在端口 4000 上,运行 它们在不同的屏幕或不同的 ssh 会话上。

nc -l 3000 # in the first screen
nc -l 4000 # in a second screen 

然后在你执行 sudo systemctl reload haproxy 以确保 HAProxy 重新加载你的新配置文件后,你可以在端口 80 上发出 http GET 请求并提供 "x-mycustom-header: Server-one" header.

您将能够在侦听端口 3000 的 netcat 实例的输出中看到请求。 现在将 header 更改为 "x-mycustom-header: Server-two" 并发出第二个 GET 请求,你会看到这次请求到达了第二个 netcat 实例,它正在侦听端口 4000,这表明这有效。

在 ArchLinux 上测试

Microsoft 团队已做出回应,确认目前无法实现。