Apache-2.2

強制 Apache proxy_balancer 到特定的工作人員

  • August 17, 2016

我想在 proxy_balancer 後面有兩個 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

我現在想做的是關閉一台伺服器並將其從池中離線,我可以使用 balancer-manager 執行此操作。然後,當我升級並啟動並執行該伺服器時 - 在返回池之前,我希望能夠訪問它,以便我可以在返回池之前對其進行完整性檢查。例如

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 }

我就是這樣做的。設置 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>

為各個伺服器設置一個池可以使事情保持一致。

用於設置 cookie ,route=p1以便平衡器可以使用 stickysession 會話親和性 - 即使用同一伺服器進行瀏覽器會話。即使會話在伺服器之間共享,這對於滾動部署也很有用,因為我不希望使用者點擊舊版本然後從新伺服器獲取 .js 文件等。

我將使用這個 cookie 來決定使用哪個池。例如,如果ROUTEIDcookie 是.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是必需的,並且每個ProxyPass變數都ProxyPassReverse需要一個interpolate

最後,我需要設置上面用於平衡器和我選擇後端的stickysession會話親和力的cookie:

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

引用自:https://serverfault.com/questions/659528