使用 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_one
或 backend_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 团队已做出回应,确认目前无法实现。
我有一个架构,其中有多个实例,但我想最大化 缓存命中率。
用户是按组定义的,我想确保属于同一组的所有用户尽可能访问同一服务器。
该应用程序是完全无状态的,但是让来自同一组的用户访问同一台服务器将显着提高所有实例的性能和内存负载。
加载主页时,我已经知道在 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_one
或 backend_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 团队已做出回应,确认目前无法实现。