1、前面已經介紹過關於haproxy的工做特性了,本文主要介紹下haproxy如何來實現web應用的動靜分離的,主要思路就是經過frontend段中定義acl訪問控制,把符合靜態內容的請求歸類到一個acl,符合動態的請求歸類到另一個acl,backend段中定義接收請求的靜態內容和動態內容的服務器,而後經過use_backend調用定義的acl便可。
javascript
2、實驗環境:
php
192.168.30.116 OS:Centos6.4 x86_64 haproxy.luojianlong.comcss
192.168.30.117 OS:Centos6.4 x86_64 static.luojianlong.comhtml
192.168.30.119 OS:Centos6.4 x86_64 dynamic.luojianlong.comjava
haproxy version:haproxy-1.4.24 web
拓撲圖以下:正則表達式
在haproxy server上安裝haproxy,這裏使用yum安裝redis
[root@haproxy ~]# yum -y install haproxy
在static server,dynamic上安裝httpd和php算法
[root@static ~]# yum -y install httpd [root@dynamic ~]# yum -y install httpd php
分別啓動static,dynamic的httpd,測試本地訪問是否正常後端
[root@static ~]# service httpd start [root@static ~]# ss -naptl | grep :80 LISTEN 0 128 :::80 :::* users:(("httpd",24245,5),("httpd",24247,5),("httpd",24248,5),("httpd",24249,5),("httpd",24250,5),("httpd",24251,5),("httpd",24252,5),("httpd",24253,5),("httpd",24254,5)) [root@static ~]# echo "static.luojianlong.com" >> /var/www/html/index.html [root@static ~]# curl 192.168.30.117 static.luojianlong.com [root@dynamic ~]# service httpd start [root@dynamic ~]# ss -anplt | grep :80 LISTEN 0 128 :::80 :::* users:(("httpd",13702,5),("httpd",13704,5),("httpd",13705,5),("httpd",13706,5),("httpd",13707,5),("httpd",13708,5),("httpd",13709,5),("httpd",13710,5),("httpd",13711,5)) [root@dynamic ~]# vi /var/www/html/index.php <?php echo "dynamic.luojianlong.com" ?> [root@dynamic ~]# curl -I http://192.168.30.119/index.php HTTP/1.1 200 OK Date: Thu, 03 Apr 2014 05:39:23 GMT Server: Apache/2.2.15 (CentOS) X-Powered-By: PHP/5.3.3 Connection: close Content-Type: text/html; charset=UTF-8
訪問都正常
下面開始配置haproxy
[root@haproxy ~]# cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak [root@haproxy ~]# vi /etc/haproxy/haproxy.cfg global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats defaults mode http log global option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen stats mode http bind 0.0.0.0:1080 stats enable stats hide-version stats uri /haproxyadmin?stats stats realm Haproxy\ Statistics stats auth admin:admin stats admin if TRUE frontend http-in bind *:80 mode http log global option httpclose option logasap option dontlognull capture request header Host len 20 capture request header Referer len 60 acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheets acl url_static path_end -i .html .jpg .jpeg .gif .png .css .js acl url_dynamic path_end -i .php .jsp use_backend static_servers if url_static use_backend dynamic_servers if url_dynamic backend static_servers balance roundrobin server imgsrv1 192.168.30.117:80 check maxconn 6000 # server imgsrv2 192.168.30.118:80 check maxconn 6000 backend dynamic_servers balance source server websrv1 192.168.30.119:80 check maxconn 1000 # server websrv2 192.168.30.120:80 check maxconn 1000
stats enable:啓用基於程序編譯時默認設置的統計報告,不能用於「frontend」區段;
stats hide-version:啓用統計報告並隱藏HAProxy版本報告,不能用於「frontend」區段。默認狀況下,統計頁面會顯示一些有用信息,包括HAProxy的版本號,然而,向全部人公開HAProxy的精確版本號是很是有風險的,由於它能幫助惡意用戶快速定位版本的缺陷和漏洞;
stats realm:啓用統計報告並高精認證領域,不能用於「frontend」區段。haproxy在讀取realm時會將其視做一個單詞,所以,中間的任何空白字符都必須使用反斜線進行轉義。此參數僅在與「stats auth」配置使用時有意義;
stats scope:啓用統計報告並限定報告的區段,不能用於「frontend」區段。當指定此語句時,統計報告將僅顯示其列舉出區段的報告信息,全部其它區段的信息將被隱藏。若是須要顯示多個區段的統計報告,此語句能夠定義屢次。須要注意的是,區段名稱檢測僅僅是以字符串比較的方式進行,它不會真檢測指定的區段是否真正存在;
stats auth:啓用帶認證的統計報告功能並受權一個用戶賬號,其不能用於「frontend」區段;
stats admin:在指定的條件知足時啓用統計報告頁面的管理級別功能,它容許經過web接口啓用或禁用服務器,不過,基於安全的角度考慮,統計報告頁面應該儘量爲只讀的。此外,若是啓用了HAProxy的多進程模式,啓用此管理級別將有可能致使異常行爲;
option http-server-close:容許服務器端關閉鏈接;
option dontlognull:訪問內容爲空的不記錄日誌;
option redispatch:在session失敗後,是否容許從新分配;
retries:用於haproxy到後端server鏈接失敗時重試次數;
option httplog:啓用記錄HTTP請求、會話狀態和計時器的功能;
option forwardfor:容許在發往服務器的請求首部中插入「X-Forwarded-For」首部;
ACL語法格式:
acl <aclname> <criterion> [flags] [operator] <value> ...
<aclname>:ACL名稱,區分字符大小寫,且其只能包含大小寫字母、數字、-(鏈接線)、_(下劃線)、.(點號)和:(冒號);haproxy中,acl能夠重名,這能夠把多個測試條件定義爲一個共同的acl;
<criterion>:測試標準,即對什麼信息發起測試;測試方式能夠由[flags]指定的標誌進行調整;而有些測試標準也能夠須要爲其在<value>以前指定一個操做符[operator];
[flags]:目前haproxy的acl支持的標誌位有3個:
-i:不區分<value>中模式字符的大小寫;
-f:從指定的文件中加載模式;
--:標誌符的強制結束標記,在模式中的字符串像標記符時使用;
<value>:acl測試條件支持的值有如下四類:
整數或整數範圍:如1024:65535表示從1024至65535;僅支持使用正整數(若是出現相似小數的標識,其爲 一般爲版本測試),且支持使用的操做符有5個,分別爲eq、ge、gt、le和lt;
字符串:支持使用「-i」以忽略字符大小寫,支持使用「\」進行轉義;若是在模式首部出現了-i,能夠在 其以前使用「--」標誌位;
正則表達式:其機制類同字符串匹配;
IP地址及網絡地址
path_beg <string>:用於測試請求的URL是否以<string>指定的模式開頭;
path_end <string>:用於測試請求的URL是否以<string>指定的模式結尾;
支持的負載均衡算法:
roundrobin:基於權重進行輪叫,在服務器的處理時間保持均勻分佈時,這是最平衡、最公平的算法。此算法是動態的,這表示其權重能夠在運行時進行調整,不過,在設計上,每一個後端服務器僅能最多接受4128個鏈接;
static-rr:基於權重進行輪叫,與roundrobin相似,可是爲靜態方法,在運行時調整其服務器權重不會生效;不過,其在後端服務器鏈接數上沒有限制;
leastconn:新的鏈接請求被派發至具備最少鏈接數目的後端服務器;在有着較長時間會話的場景中推薦使用此算法,如LDAP、SQL等,其並不太適用於較短會話的應用層協議,如HTTP;此算法是動態的,能夠在運行時調整其權重;
source:將請求的源地址進行hash運算,並由後端服務器的權重總數相除後派發至某匹配的服務器;這可使得同一個客戶端IP的請求始終被派發至某特定的服務器;不過,當服務器權重總數發生變化時,如某服務器宕機或添加了新的服務器,許多客戶端的請求可能會被派發至與此前請求不一樣的服務器;經常使用於負載均衡無cookie功能的基於TCP的協議;其默認爲靜態,不過也可使用hash-type修改此特性;
uri:對URI的左半部分(「問題」標記以前的部分)或整個URI進行hash運算,並由服務器的總權重相除後派發至某匹配的服務器;這可使得對同一個URI的請求老是被派發至某特定的服務器,除非服務器的權重總數發生了變化;此算法經常使用於代理緩存或反病毒代理以提升緩存的命中率;須要注意的是,此算法僅應用於HTTP後端服務器場景;其默認爲靜態算法,不過也可使用hash-type修改此特性;
url_param:經過<argument>爲URL指定的參數在每一個HTTP GET請求中將會被檢索;若是找到了指定的參數且其經過等於號「=」被賦予了一個值,那麼此值將被執行hash運算並被服務器的總權重相除後派發至某匹配的服務器;此算法能夠經過追蹤請求中的用戶標識進而確保同一個用戶ID的請求將被送往同一個特定的服務器,除非服務器的總權重發生了變化;若是某請求中沒有出現指定的參數或其沒有有效值,則使用輪叫算法對相應請求進行調度;此算法默認爲靜態的,不過其也可使用hash-type修改此特性;
hdr(<name>):對於每一個HTTP請求,經過<name>指定的HTTP首部將會被檢索;若是相應的首部沒有出現或其沒有有效值,則使用輪叫算法對相應請求進行調度;其有一個可選選項「use_domain_only」,可在指定檢索相似Host類的首部時僅計算域名部分,以下降hash算法的運算量;此算法默認爲靜態的,不過其也可使用hash-type修改此特性;
hash-type <method>
定義用於將hash碼映射至後端服務器的方法;其不能用於frontend區段;可用方法有map-based和consistent,在大多數場景下推薦使用默認的map-based方法。
map-based:hash表是一個包含了全部在線服務器的靜態數組。其hash值將會很是平滑,會將權重考慮在列,但其爲靜態方法,對在線服務器的權重進行調整將不會生效,這意味着其不支持慢速啓動。此外,挑選服務器是根據其在數組中的位置進行的,所以,當一臺服務器宕機或添加了一臺新的服務器時,大多數鏈接將會被從新派發至一個與此前不一樣的服務器上,對於緩存服務器的工做場景來講,此方法不甚適用。
consistent:hash表是一個由各服務器填充而成的樹狀結構;基於hash鍵在hash樹中查找相應的服務器時,最近的服務器將被選中。此方法是動態的,支持在運行時修改服務器權重,所以兼容慢速啓動的特性。添加一個新的服務器時,僅會對一小部分請求產生影響,所以,尤爲適用於後端服務器爲cache的場景。不過,此算法不甚平滑,派發至各服務器的請求未必能達到理想的均衡效果,所以,可能須要不時的調整服務器的權重以得到更好的均衡性。
這裏就寫這麼多了,更多,請查看官方網站:http://haproxy.1wt.eu/
接下來,啓動haproxy
[root@haproxy ~]# service haproxy start Starting haproxy: [ OK ] [root@haproxy ~]# ss -anptl | grep :80 LISTEN 0 128 *:80 *:* users:(("haproxy",20436,6))
正常啓動,打開瀏覽器訪問管理界面:http://192.168.30.116:1080/haproxyadmin?stats
發現定義的static_servers和dynamic_servers已經正常工做
haproxy的管理界面支持直接禁用backend_server,使客戶端沒法訪問:
接下來驗證下動靜分離的效果,打開瀏覽器訪問http://192.168.30.116/index.html
發現訪問的192.168.30.117,爲靜態內容服務器
訪問http://192.168.30.116/index.php
發現訪問的192.168.30.119,爲動態內容服務器
到此已經實現了動靜分離的效果。