强制 Apache proxy_balancer 到特定的 worker

强制 Apache proxy_balancer 到特定的 worker

我希望在 proxy_balancer 后面拥有两个 tomcat 服务器,这样我就可以进行滚动部署。

我已经完成了这项工作,因此我可以关闭一个 tomcat,另一个 tomcat 负责处理未来的请求

<Proxy balancer://production>
    BalancerMember http://10.10.10.111:8080 route=s1
    BalancerMember http://10.10.10.112:8080 route=s2
    ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass /services balancer://production/services
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/;" env=BALANCER_ROUTE_CHANGED

我现在想做的是关闭一台服务器并将其从池中移除,我可以使用平衡器管理器来完成此操作。然后,当我升级并启动并运行该服务器时 - 在返回池之前,我希望能够访问它,以便在返回池之前对其进行完整性检查。例如

ProxyPass /sanity_check http://10.10.10.111:8080/services

但这样做不行,因为服务器会将自身重定向到 /services 并通过平衡器。我可以使用单独的域来实现这一点,但我想避免这种情况。

我考虑过根据 URL 参数设置 cookie,这可能可行,但做起来很麻烦。是否有一些功能可以轻松实现这一点。例如,在 HAProxy 中我可以这样做

use-server tomcat_01 if { path_end TOMCAT_01 }
use-server tomcat_02 if { path_end TOMCAT_02 }

答案1

我是这样做的。设置 3 个平衡器池 - 一个主平衡器池和一个用于每个单独服务器的平衡器池:

<Proxy balancer://tomcat1>
   BalancerMember http://10.10.10.111:8080 route=t1
   ProxySet stickysession=ROUTEID
</Proxy>
<Proxy balancer://tomcat2>
   BalancerMember http://10.10.10.112:8080 route=t2
   ProxySet stickysession=ROUTEID
</Proxy>
<Proxy balancer://production>
   BalancerMember http://10.10.10.111:8080 route=p1
   BalancerMember http://10.10.10.112:8080 route=p2
   ProxySet stickysession=ROUTEID
</Proxy>

为各个服务器设立一个池可以保持一致性。

用于route=p1设置 cookie,以便平衡器可以使用 stickysession 会话亲和性 - 即对浏览器会话使用同一服务器。即使会话在服务器之间共享,这对于滚动部署也很有用,因为我不希望用户使用旧版本,然后从新服务器获取 .js 文件等。

我将使用此 cookie 来决定使用哪个池。例如,如果 cookieROUTEID.t1(请注意前导点 - 这显然是必要的),则使用 tomcat1 平衡器。

# Default to production pool 
SetEnvIf Request_URI "/" TARGET_POOL=production

SetEnvIf Cookie "ROUTEID=.t1" TARGET_POOL=tomcat1
SetEnvIf Cookie "ROUTEID=.t2" TARGET_POOL=tomcat2

一旦设置了路由 cookie,会话将继续通过该后端平衡器。

我可以通过在 URL 末尾附加一个标识符来选择我想要使用的平衡器,以选择我想要用于此会话的平衡器池。

将环境变量设置TARGET_POOL为适当的池

SetEnvIf Request_URI "/select_tomcat1$" TARGET_POOL=tomcat1
SetEnvIf Request_URI "/select_tomcat2$" TARGET_POOL=tomcat2
SetEnvIf Request_URI "/select_pool$" TARGET_POOL=production

现在我可以TARGET_POOL将请求传递给选定的后端平衡器

ProxyPassInterpolateEnv On
ProxyPass /services balancer://${TARGET_POOL}/services interpolate
ProxyPassReverse /services balancer://${TARGET_POOL}/services interpolate

请注意,这些变量要起作用ProxyPassInterpolateEnv On是必需的,并且每个变量ProxyPassProxyPassReverse需要一个interpolate

最后,我需要设置上面平衡器用于 stickysession 会话亲和性的 cookie 以及我选择后端的 cookie:

Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/;" env=BALANCER_ROUTE_CHANGED

相关内容