一、前面已經介紹過關于haproxy的工作特性了,本文主要介紹下haproxy如何來實作web應用的動靜分離的,主要思路就是通過frontend段中定義acl通路控制,把符合靜态内容的請求歸類到一個acl,符合動态的請求歸類到另外一個acl,backend段中定義接收請求的靜态内容和動态内容的伺服器,然後通過use_backend調用定義的acl即可。
二、實驗環境:
192.168.30.116 OS:Centos6.4 x86_64 haproxy.luojianlong.com
192.168.30.117 OS:Centos6.4 x86_64 static.luojianlong.com
192.168.30.119 OS:Centos6.4 x86_64 dynamic.luojianlong.com
haproxy version:haproxy-1.4.24
拓撲圖如下:
<a href="http://s3.51cto.com/wyfs02/M02/23/A3/wKiom1M88sHiF5ofAAEnJ_tv2Oo134.jpg" target="_blank"></a>
在haproxy server上安裝haproxy,這裡使用yum安裝
1
<code>[root@haproxy ~]</code><code># yum -y install haproxy</code>
在static server,dynamic上安裝httpd和php
2
<code>[root@static ~]</code><code># yum -y install httpd</code>
<code>[root@dynamic ~]</code><code># yum -y install httpd php</code>
分别啟動static,dynamic的httpd,測試本地通路是否正常
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<code>[root@static ~]</code><code># service httpd start</code>
<code>[root@static ~]</code><code># ss -naptl | grep :80</code>
<code>LISTEN 0 128 :::80 :::* </code><code>users</code><code>:((</code><code>"httpd"</code><code>,24245,5),(</code><code>"httpd"</code><code>,24247,5),(</code><code>"httpd"</code><code>,24248,5),(</code><code>"httpd"</code><code>,24249,5),(</code><code>"httpd"</code><code>,24250,5),(</code><code>"httpd"</code><code>,24251,5),(</code><code>"httpd"</code><code>,24252,5),(</code><code>"httpd"</code><code>,24253,5),(</code><code>"httpd"</code><code>,24254,5))</code>
<code>[root@static ~]</code><code># echo "static.luojianlong.com" >> /var/www/html/index.html</code>
<code>[root@static ~]</code><code># curl 192.168.30.117</code>
<code>static.luojianlong.com</code>
<code>[root@dynamic ~]</code><code># service httpd start</code>
<code>[root@dynamic ~]</code><code># ss -anplt | grep :80</code>
<code>LISTEN 0 128 :::80 :::* </code><code>users</code><code>:((</code><code>"httpd"</code><code>,13702,5),(</code><code>"httpd"</code><code>,13704,5),(</code><code>"httpd"</code><code>,13705,5),(</code><code>"httpd"</code><code>,13706,5),(</code><code>"httpd"</code><code>,13707,5),(</code><code>"httpd"</code><code>,13708,5),(</code><code>"httpd"</code><code>,13709,5),(</code><code>"httpd"</code><code>,13710,5),(</code><code>"httpd"</code><code>,13711,5))</code>
<code>[root@dynamic ~]</code><code># vi /var/www/html/index.php</code>
<code><?php</code>
<code>echo</code> <code>"dynamic.luojianlong.com"</code>
<code>?></code>
<code>[root@dynamic ~]</code><code># curl -I http://192.168.30.119/index.php</code>
<code>HTTP</code><code>/1</code><code>.1 200 OK</code>
<code>Date: Thu, 03 Apr 2014 05:39:23 GMT</code>
<code>Server: Apache</code><code>/2</code><code>.2.15 (CentOS)</code>
<code>X-Powered-By: PHP</code><code>/5</code><code>.3.3</code>
<code>Connection: close</code>
<code>Content-Type: text</code><code>/html</code><code>; charset=UTF-8</code>
通路都正常
下面開始配置haproxy
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<code>[root@haproxy ~]</code><code># cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak</code>
<code>[root@haproxy ~]</code><code># vi /etc/haproxy/haproxy.cfg</code>
<code>global</code>
<code> </code>
<code> </code><code>log 127.0.0.1 local2</code>
<code> </code><code>chroot </code><code>/var/lib/haproxy</code>
<code> </code><code>pidfile </code><code>/var/run/haproxy</code><code>.pid</code>
<code> </code><code>maxconn 4000</code>
<code> </code><code>user haproxy</code>
<code> </code><code>group haproxy</code>
<code> </code><code>daemon</code>
<code> </code>
<code> </code><code>stats socket </code><code>/var/lib/haproxy/stats</code>
<code>defaults</code>
<code> </code><code>mode http</code>
<code> </code><code>log global</code>
<code> </code><code>option httplog</code>
<code> </code><code>option dontlognull</code>
<code> </code><code>option http-server-close</code>
<code> </code><code>option forwardfor except 127.0.0.0</code><code>/8</code>
<code> </code><code>option redispatch</code>
<code> </code><code>retries 3</code>
<code> </code><code>timeout http-request 10s</code>
<code> </code><code>timeout queue 1m</code>
<code> </code><code>timeout connect 10s</code>
<code> </code><code>timeout client 1m</code>
<code> </code><code>timeout server 1m</code>
<code> </code><code>timeout http-keep-alive 10s</code>
<code> </code><code>timeout check 10s</code>
<code> </code><code>maxconn 3000</code>
<code>listen stats</code>
<code> </code><code>mode http</code>
<code> </code><code>bind 0.0.0.0:1080</code>
<code> </code><code>stats </code><code>enable</code>
<code> </code><code>stats hide-version</code>
<code> </code><code>stats uri </code><code>/haproxyadmin</code><code>?stats</code>
<code> </code><code>stats realm Haproxy\ Statistics</code>
<code> </code><code>stats auth admin:admin</code>
<code> </code><code>stats admin </code><code>if</code> <code>TRUE</code>
<code>frontend http-</code><code>in</code>
<code> </code><code>bind *:80</code>
<code> </code><code>log global</code>
<code> </code><code>option httpclose</code>
<code> </code><code>option logasap</code>
<code> </code><code>option dontlognull</code>
<code> </code><code>capture request header Host len 20</code>
<code> </code><code>capture request header Referer len 60</code>
<code> </code><code>acl url_static path_beg -i </code><code>/static</code> <code>/images</code> <code>/javascript</code> <code>/stylesheets</code>
<code> </code><code>acl url_static path_end -i .html .jpg .jpeg .gif .png .css .js</code>
<code> </code><code>acl url_dynamic path_end -i .php .jsp</code>
<code> </code><code>use_backend static_servers </code><code>if</code> <code>url_static</code>
<code> </code><code>use_backend dynamic_servers </code><code>if</code> <code>url_dynamic</code>
<code>backend static_servers</code>
<code> </code><code>balance roundrobin</code>
<code> </code><code>server imgsrv1 192.168.30.117:80 check maxconn 6000</code>
<code># server imgsrv2 192.168.30.118:80 check maxconn 6000</code>
<code>backend dynamic_servers</code>
<code> </code><code>balance </code><code>source</code>
<code> </code><code>server websrv1 192.168.30.119:80 check maxconn 1000</code>
<code># server websrv2 192.168.30.120:80 check maxconn 1000</code>
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的場景。不過,此算法不甚平滑,派發至各伺服器的請求未必能達到理想的均衡效果,是以,可能需要不時的調整伺服器的權重以獲得更好的均衡性。
接下來,啟動haproxy
<code>[root@haproxy ~]</code><code># service haproxy start</code>
<code>Starting haproxy: [ OK ]</code>
<code>[root@haproxy ~]</code><code># ss -anptl | grep :80</code>
<code>LISTEN 0 128 *:80 *:* </code><code>users</code><code>:((</code><code>"haproxy"</code><code>,20436,6))</code>
<a href="http://s3.51cto.com/wyfs02/M02/23/A4/wKiom1M8_lGgGILtAAcwdnD_TDI817.jpg" target="_blank"></a>
發現定義的static_servers和dynamic_servers已經正常工作
haproxy的管理界面支援直接禁用backend_server,使用戶端無法通路:
<a href="http://s3.51cto.com/wyfs02/M00/23/A5/wKioL1M8_o-TFrF7AAHNf4WpYUQ527.jpg" target="_blank"></a>
<a href="http://s3.51cto.com/wyfs02/M02/23/A5/wKioL1M8_z3R9VTTAABE_NRbwjc525.jpg" target="_blank"></a>
發現通路的192.168.30.117,為靜态内容伺服器
<a href="http://s3.51cto.com/wyfs02/M02/23/A5/wKioL1M8_7WgJioHAABCZctrMxw758.jpg" target="_blank"></a>
發現通路的192.168.30.119,為動态内容伺服器
到此已經實作了動靜分離的效果。
本文轉自ljl_19880709 51CTO部落格,原文連結:http://blog.51cto.com/luojianlong/1389630,如需轉載請自行聯系原作者