緩存角度的Apache負載均衡
Apache負載均很設置很多情況下都是根據tomacat來完成的,現在這片文章介紹的是關于反向代理實現apache負載均衡的配置過程,首先我們來參考一下前人的操作過程,根據那個方案來修改我們的實際操作。
下基于反向代理實現Apache負載均衡
初步設想:
考慮到對不同的 App Server 而言, 實現 Session 復制的配置各不相同(通常是需要配置集群), 因此從通用的角度, 覺得使用 session sticky 方式實現的負載均衡比較方便(沒有看到有資料說 lighttpd 能夠實現 session sticky, 所以決定使用 Apache 試試)
環境準備:
1、下載安裝 Apache(不多廢話了)
2、準備兩個運行同樣程序的 Web 服務器,這里使用的是 Tomcat 5.5, 并使用一個 jsp 文件作為測試文件
3、下載安裝 JMeter ( jakarta-jmeter-2.2), 用于壓力測試, 驗證apache負載均衡的效果
測試jsp文件說明:
1、顯示當前運行的服務器的 IP 地址及端口號, 這樣從返回的頁面就能夠知道是運行在哪一個 Web 服務器上的了
2、統計每個客戶端(不同的 session)向同一臺服務器發出請求的次數, 通過這個計數可以驗證是否實現了 session sticky
3、通過 clear 請求參數(即 .../test.jsp?clear=1)清除請求次數的計數結果, 以便進行下一次測試
4、模擬 JSESSIONID +jvmRoute 的機制, 自行實現了一個 STICK_PORT_TOKEN 的 Cookie, 直接使用不同服務器的 HTTP 端口號作為 route#p#
Apache負載均衡配置:
簡單的反向代理
- ProxyRequests Off
- <Proxy *>
- Order deny,allow
- Allow from all
- </Proxy>
- ProxyPass /1 http://localhost:8080/test
- #ProxyPassReverse /1 http://localhost:8080/test
- ProxyPass /2 http://localhost:18080/test
- #ProxyPassReverse /2 http://localhost:18080/test
- # 2)非 stickysession 的 balance
- ProxyPass /3 balancer://non-sticky-cluster nofailover=On
- <Proxy balancer://non-sticky-cluster>
- BalancerMember http://localhost:8080/test
- BalancerMember http://localhost:18080/test smax=10
- </Proxy>
- # 3)stickysession 的 balance
- ProxyPass /4 balancer://sticky-cluster stickysession=STICK_PORT_TOKEN nofailover=On
- <Proxy balancer://sticky-cluster>
- BalancerMember http://localhost:8080/test route=8080
- BalancerMember http://localhost:18080/test route=18080 loadfactor=2
- </Proxy>
這個配置分為3個部分, 包括了 1)簡單的反向代理, 2)非 session sticky 的 load balance, 以及 3)session sticky 的 load balance 三種方式的配置(這里假設兩個 Tomcat 服務器的 HTTP 服務被配置在 8080 和 18080 端口), 其中第 2) 和 3) 的配置中 "nofailover=On" 適合于沒有 session 復制的情況下, 這種情況下, 如果其中一臺 HTTP 服務器出錯, 那么原來分配在這個出錯機器上的瀏覽器客戶端不會被自動轉移到另外的服務器上, 必須重新啟動瀏覽器才能將請求分配到另外一臺服務器上去.#p#
使用 JMeter 測試結果:
使用 JMeter 對 "3)session sticky 的 load balance" 的效果進行測試, 通過壓力測試的方式, 檢查兩臺 Tomcat 服務器被分配到的請求數量(注意如果重復測試, 在下一次測試開始之前請對每個 Tomcat 服務器執行 .../test.jsp?clear=1 的請求, 清除上一次的計數結果).
從測試結果可見: 50個線程中有21個被分配在 8080 端口的服務器上, 29個則被分配到 18080 端口的服務器; 另外, 所有的 session 請求次數都是 20 次, 說明 session sticky 達到了預期的效果.
補充一下對 PHP 的 session sticky 配置問題:
對于使用 PHP 的朋友可能會在這里遇到一些問題,也許是因為 Apache 文檔的誤導,大家可能會照著上面的例子把 JSESSIONID 換為 PHPSESSID,但是這樣是不行的!如果你有時間看看代碼 modules/proxy/mod_proxy_balancer.c lines 195 to 210 也許你會發現一些問題,Apache 實際上在找一個類似于“balancer.www1"的 SESSIONID,我們可以配置 TOMCAT 來實現這種形式的 SESSIONID 但是 PHP 卻沒有這個功能。但是,幸好我們能通過 Apache 的 Rewrite 功能來做這個事情。
首先,假設我們后臺有兩臺機器 www1.james.com 和 www2.james.com 我們先為他們配置 VirtualHost :
- RewriteEngine on
- RewriteRule .* - [CO=BALANCEID:balancer.www{1或者2}:.james.com]
然后,我們在前臺做apache負載均衡的機器上(假設為www.james.com)配置如下:
- ProxyPass /bt balancer://sticky-cluster lbmethod=byrequests stickysession=BALANCEID nofailover=On
- ProxyPassReverse /bt balancer://sticky-cluster
- <Proxy balancer://sticky-cluster>
- BalancerMember http://www2.james.com/6d/session_test.php route=www2
- BalancerMember http://www1.james.com/session_test.php route=www1
- </Proxy>
重啟 Apache 大功告成,我們訪問 http://mail.james.com/bt 發現 .james.com 的 COOKIE 中除了 PHPSESSID 還出現了 BALANCEID,到這里我們已經成功了一半;然后,我們可以到apache 的 site_error log 中看到以下信息(設置 LogLevel debug):#p#
第一次登錄:
- BALANCER: Found value (null) for stickysession BALANCEID
- Entering byrequests for BALANCER (balancer://sticky-cluster)
第二次登錄:
- Found value balancer.www2 for stickysession BALANCEID
- Found route www2
之后,該用戶的 session 就不會跳到 www1 上去了,直到 cookie 或 session 過期。這樣,我們就達到了“stick session"的目的了,真是形象啊,哈哈:)
以下是一些關于緩存的配置步驟摘要:
創建/var/www/proxy,設置apache服務所用戶可寫,mod_proxy配置樣例:反相代理緩存+緩存架設前臺的www.example.com反向代理后臺的www.backend.com的8080端口服務。修改:httpd.conf
- <VirtualHost *>
- ServerName www.example.com
- ServerAdmin admin@example.com
- # reverse proxy setting
- ProxyPass / http://www.backend.com:8080/
- ProxyPassReverse / http://www.backend.com:8080/
- # cache dir root
- CacheRoot "/var/www/proxy"
- # max cache storage
- CacheSize 50000000
- # hour: every 4 hour
- CacheGcInterval 4
- # max page expire time: hour
- CacheMaxExpire 240
- # Expire time = (now - last_modified) * CacheLastModifiedFactor
- CacheLastModifiedFactor 0.1
- # defalt expire tag: hour
- CacheDefaultExpire 1
- # force complete after precent of content retrived: 60-90%
- CacheForceCompletion 80
- CustomLog /usr/local/apache/logs/dev_access_log combined
- </VirtualHost>