說明:本篇文章大部分參考http://sohudrgon.blog.51cto.com/3088108/1602198
一、HAProxy簡介
1、什麼是HAProxy
HAProxy是免費、極速且可靠的用于為TCP和基于HTTP應用程式提供高可用、負載均衡和代理服務的解決方案,尤其适用于高負載且需要持久連接配接或7層處理機制的web站點。HAProxy特别适用于那些負載特大的web站點,這些站點通常又需要會話保持或七層處理。HAProxy運作在目前的硬體上,完全可以支援數以萬計的并發連接配接。并且它的運作模式使得它可以很簡單安全的整合進您目前的架構中, 同時可以保護你的web伺服器不被暴露到網絡上。
HAProxy實作了一種事件驅動, 單一程序模型,此模型支援非常大的并發連接配接數。多程序或多線程模型受記憶體限制 、系統排程器限制以及無處不在的鎖限制,很少能處理數千并發連接配接。事件驅動模型因為在有更好的資源和時間管理的使用者空間(User-Space) 實作所有這些任務,是以沒有這些問題。此模型的弊端是,在多核系統上,這些程式通常擴充性較差。這就是為什麼他們必須進行優化以 使每個CPU時間片(Cycle)做更多的工作。
2、haproxy 性能特點
HAProxy借助于OS上幾種常見的技術來實作性能的最大化。
- 單程序、事件驅動模型顯著降低了上下文切換的開銷及記憶體占用。
- O(1)事件檢查器(event checker)允許其在高并發連接配接中對任何連接配接的任何事件實作即時探測。
- 在任何可用的情況下,單緩沖(single buffering)機制能以不複制任何資料的方式完成讀寫操作,這會節約大量的CPU時鐘周期及記憶體帶寬;
- 借助于Linux 2.6 (>= 2.6.27.19)上的splice()系統調用,HAProxy可以實作零複制轉發(Zero-copy forwarding),在Linux 3.5及以上的OS中還可以實作零複制啟動(zero-starting);
- MRU記憶體配置設定器在固定大小的記憶體池中可實作即時記憶體配置設定,這能夠顯著減少建立一個會話的時長;
- 樹型存儲:側重于使用作者多年前開發的彈性二叉樹,實作了以O(log(N))的低開銷來保持計時器指令、保持運作隊列指令及管理輪詢及最少連接配接隊列;
- 優化的HTTP首部分析:優化的首部分析功能避免了在HTTP首部分析過程中重讀任何記憶體區域;
- 精心地降低了昂貴的系統調用,大部分工作都在使用者空間完成,如時間讀取、緩沖聚合及檔案描述符的啟用和禁用等;
所有的這些細微之處的優化實作了在中等規模負載之上依然有着相當低的CPU負載,甚至于在非常高的負載場景中,5%的使用者空間占用率和95%的系統空間占用率也是非常普遍的現象,這意味着HAProxy程序消耗比系統空間消耗低20倍以上。是以,對OS進行性能調優是非常重要的。即使使用者空間的占用率提高一倍,其CPU占用率也僅為10%,這也解釋了為何7層處理對性能影響有限這一現象。由此,在高端系統上HAProxy的7層性能可輕易超過硬體負載均衡裝置。
在生産環境中,在7層處理上使用HAProxy作為昂貴的高端硬體負載均衡裝置故障故障時的緊急解決方案也時長可見。硬體負載均衡裝置在“封包”級别處理請求,這在支援跨封包請求(request across multiple packets)有着較高的難度,并且它們不緩沖任何資料,是以有着較長的響應時間。對應地,軟體負載均衡裝置使用TCP緩沖,可建立極長的請求,且有着較大的響應時間。
3、負載均衡器的性能評估重要因素
- 會話率 :機關時間内的處理的請求數
- 會話并發能力:并發處理能力
- 資料率:處理資料能力
經過官方測試統計,haproxy 機關時間處理的最大請求數為20000個,可以同時維護40000-50000個并發連接配接,最大資料處理能力為10Gbps。綜合上述,haproxy是性能優越的負載均衡、反向代理伺服器。好了,下面我們來說說haproxy的配置檔案。
二、 配置haproxy
1、配置檔案的格式
HAProxy的配置處理3類來主要參數來源:
- 最優先處理的指令行參數;
- “global”配置段,用于設定全局配置參數;
- proxy相關配置段,如“defaults”、“listen”、“frontend”和“backend”;
2、支援的時間格式
一些包含了值的參數表示時間,如逾時時長。這些值一般以毫秒為機關,但也可以使用其它的時間機關字尾。
- us: 微秒(microseconds),即1/1000000秒;
- ms: 毫秒(milliseconds),即1/1000秒;
- s: 秒(seconds);
- m: 分鐘(minutes);
- h:小時(hours);
- d: 天(days);
3、簡單案例
下面的例子配置了一個監聽在所有接口的80端口上HTTP proxy服務,它轉發所有的請求至後端監聽在127.0.0.1:8000上的"server"。
1 2 3 4 5 6 7 8 9 10 11 12 13 | global daemon maxconn 25600 defaults mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms frontend http-in bind *:80 default_backend servers backend servers server server1 127.0.0.1:8080 maxconn 32 |
4、全局配置
注,“global”配置中的參數為程序級别的參數,且通常與其運作的OS相關。
(1).程序管理及安全相關的參數
- chroot <jail dir>:修改haproxy的工作目錄至指定的目錄并在放棄權限之前執行chroot()操作,可以提升haproxy的安全級别,不過需要注意的是要確定指定的目錄為空目錄且任何使用者均不能有寫權限;
- daemon:讓haproxy以守護程序的方式工作于背景,其等同于“-D”選項的功能,當然,也可以在指令行中以“-db”選項将其禁用;
- gid <number>:以指定的GID運作haproxy,建議使用專用于運作haproxy的GID,以免因權限問題帶來風險;
- group <group name>:同gid,不過指定的組名;
- log <address> <facility> [max level [min level]]:定義全局的syslog伺服器,最多可以定義兩個;
- log-send-hostname [<string>]:在syslog資訊的首部添加目前主機名,可以為“string”指定的名稱,也可以預設使用目前主機名;
- nbproc <number>:指定啟動的haproxy程序個數,隻能用于守護程序模式的haproxy;預設隻啟動一個程序,鑒于調試困難等多方面的原因,一般隻在單程序僅能打開少數檔案描述符的場景中才使用多程序模式;
- pidfile:将所有程序的pid寫入檔案啟動程序的使用者必須有權限通路此檔案
- uid:以指定的UID身份運作haproxy程序;
- ulimit-n:設定每程序所能夠打開的最大檔案描述符數目,預設情況下其會自動進行計算,是以不推薦修改此選項;
- user:同uid,但使用的是使用者名;
- node:定義目前節點的名稱,用于HA場景中多haproxy程序共享同一個IP位址時;
- description:目前執行個體的描述資訊;
(2).性能調整相關的參數
- maxconn <number>:設定每個haproxy程序所接受的最大并發連接配接數,其等同于指令行選項“n”;“ulimit n”自動計算的結果正是參照此參數設定的;
- maxpipes <number>:haproxy使用pipe完成基于核心的tcp封包重組,此選項則用于設定每程序所允許使用的最大pipe個數;每個pipe會打開兩個檔案描述符,是以,“ulimit n”自動計算時會根據需要調大此值;預設為maxconn/4,其通常會顯得過大;
- noepoll:在Linux系統上禁用epoll機制;
- nokqueue:在BSE系統上禁用kqueue機制;
- nopoll:禁用poll機制;
- nosepoll:在Linux禁用啟發式epoll機制;
- nosplice:禁止在Linux套接字上使用核心tcp重組,這會導緻更多的recv/send系統調用;不過,在Linux 2.6.2528系列的核心上,tcp重組功能有bug存在;
- spreadchecks <0..50, in percent>:在haproxy後端有着衆多伺服器的場景中,在精确的時間間隔後統一對衆伺服器進行健康狀況檢查可能會帶來意外問題;此選項用于将其檢查的時間間隔長度上增加或減小一定的随機時長;
- tune.bufsize <number>:設定buffer的大小,同樣的記憶體條件小,較小的值可以讓haproxy有能力接受更多的并發連接配接,較大的值可以讓某些應用程式使用較大的cookie資訊;預設為16384,其可以在編譯時修改,不過強烈建議使用預設值;
- tune.chksize <number>:設定檢查緩沖區的大小,機關為位元組;更大的值有助于在較大的頁面中完成基于字元串或模式的文本查找,但也會占用更多的系統資源;不建議修改;
- tune.maxaccept <number>:設定haproxy程序核心排程運作時一次性可以接受的連接配接的個數,較大的值可以帶來較大的吞吐率,預設在單程序模式下為100,多程序模式下為8,設定為1可以禁止此限制;一般不建議修改;
- tune.maxpollevents <number>:設定一次系統調用可以處理的事件最大數,預設值取決于OS;其值小于200時可節約帶寬,但會略微增大網絡延遲,而大于200時會降低延遲,但會稍稍增加網絡帶寬的占用量;
- tune.maxrewrite <number>:設定為首部重寫或追加而預留的緩沖空間,建議使用1024左右的大小;在需要使用更大的空間時,haproxy會自動增加其值;
- tune.rcvbuf.server <number>:設定核心套接字中服務端或用戶端接收緩沖的大小,機關為位元組;強烈推薦使用預設值;
5、代理
代理相關的配置可以如下配置段中,
- defaults <name>
- frontend <name>
- backend <name>
- listen <name>
“defaults”段用于為所有其它配置段提供預設參數,這配置預設配置參數可由下一個“defaults”所重新設定。
“frontend”段用于定義一系列監聽的套接字,這些套接字可接受用戶端請求并與之建立連接配接。
“backend”段用于定義一系列“後端”伺服器,代理将會将對應用戶端的請求轉發至這些伺服器。
“listen”段通過關聯“前端”和“後端”定義了一個完整的代理,通常隻對TCP流量有用。
注,所有代理的名稱隻能使用大寫字母、小寫字母、數字、-(中線)、_(下劃線)、.(點号)和:(冒号)。此外,ACL名稱會區分字母大小寫。更詳細的配置資訊,請查閱官方文檔 。
三、配置檔案中的關鍵字參考
1、 balance
balance <algorithm> [ <arguments> ]
balance url_param <param> [check_post [<max_wait>]]
定義負載均衡算法,可用于“defaults”、“listen”和“backend”。<algorithm>用于在負載均衡場景中挑選一個server,其僅應用于持久資訊不可用的條件下或需要将一個連接配接重新派發至另一個伺服器時。支援的算法有:
- 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類的首部時僅計算域名部分(比如通過www.magedu.com來說,僅計算magedu字元串的hash值)以降低hash算法的運算量;此算法預設為靜态的,不過其也可以使用hash-type修改此特性;
2、 bind
bind [<address>]:<port_range> [, ...]
bind [<address>]:<port_range> [, ...] interface <interface>
此指令僅能用于frontend和listen區段,用于定義一個或幾個監聽的套接字。
- <address>:可選選項,其可以為主機名、IPv4位址、IPv6位址或*;省略此選項、将其指定為*或0.0.0.0時,将監聽目前系統的所有IPv4位址;
- <port_range>:可以是一個特定的TCP端口,也可是一個端口範圍(如5005-5010),代理伺服器将通過指定的端口來接收用戶端請求;需要注意的是,每組監聽的套接字<address:port>在同一個執行個體上隻能使用一次,而且小于1024的端口需要有特定權限的使用者才能使用,這可能需要通過uid參數來定義;
- <interface>:指定實體接口的名稱,僅能在Linux系統上使用;其不能使用接口别名,而僅能使用實體接口名稱,而且隻有管理有權限指定綁定的實體接口;
3、mode
mode { tcp|http|health }:設定執行個體的運作模式或協定。當實作内容交換時,前端和後端必須工作于同一種模式(一般說來都是HTTP模式),否則将無法啟動執行個體。
- tcp:執行個體運作于純TCP模式,在用戶端和伺服器端之間将建立一個全雙工的連接配接,且不會對7層封包做任何類型的檢查;此為預設模式,通常用于SSL、SSH、SMTP等應用;
- http:執行個體運作于HTTP模式,用戶端請求在轉發至後端伺服器之前将被深度分析,所有不與RFC格式相容的請求都會被拒絕;
- health:執行個體工作于health模式,其對入站請求僅響應“OK”資訊并關閉連接配接,且不會記錄任何日志資訊;此模式将用于響應外部元件的健康狀态檢查請求;目前業講,此模式已經廢棄,因為tcp或http模式中的monitor關鍵字可完成類似功能;
4、 hash-type
hash-type <method>:定義用于将hash碼映射至後端伺服器的方法;其不能用于frontend區段;可用方法有map-based和consistent,在大多數場景下推薦使用預設的map-based方法。注意在後端是緩存伺服器是最好使用consistent,避免伺服器的增減進而影響緩存的效果!
- map-based:hash表是一個包含了所有線上伺服器的靜态數組。其hash值将會非常平滑,會将權重考慮在列,但其為靜态方法,對線上伺服器的權重進行調整将不會生效,這意味着其不支援慢速啟動。此外,挑選伺服器是根據其在數組中的位置進行的,是以,當一台伺服器當機或添加了一台新的伺服器時,大多數連接配接将會被重新派發至一個與此前不同的伺服器上,對于緩存伺服器的工作場景來說,此方法不甚适用。
- consistent:hash表是一個由各伺服器填充而成的樹狀結構;基于hash鍵在hash樹中查找相應的伺服器時,最近的伺服器将被選中。此方法是動态的,支援在運作時修改伺服器權重,是以相容慢速啟動的特性。添加一個新的伺服器時,僅會對一小部分請求産生影響,是以,尤其适用于後端伺服器為cache的場景。不過,此算法不甚平滑,派發至各伺服器的請求未必能達到理想的均衡效果,是以,可能需要不時的調整伺服器的權重以獲得更好的均衡性。
5、log
log global
log <address> <facility> [<level> [<minlevel>]]:為每個執行個體啟用事件和流量日志,是以可用于所有區段。每個執行個體最多可以指定兩個log參數,不過,如果使用了“log global”且"global"段已經定了兩個log參數時,多餘了log參數将被忽略。
- global:目前執行個體的日志系統參數同"global"段中的定義時,将使用此格式;每個執行個體僅能定義一次“log global”語句,且其沒有任何額外參數;
- <address>:定義日志發往的位置,其格式之一可以為<IPv4_address:PORT>,其中的port為UDP協定端口,預設為514;格式之二為Unix套接字檔案路徑,但需要留心chroot應用及使用者的讀寫權限;
- <facility>:可以為syslog系統的标準facility之一;
- <level>:定義日志級别,即輸出資訊過濾器,預設為所有資訊;指定級别時,所有等于或高于此級别的日志資訊将會被發送;
6、 maxconn
maxconn <conns>:設定一個前端的最大并發連接配接數,是以,其不能用于backend區段。對于大型站點來說,可以盡可能提高此值以便讓haproxy管理連接配接隊列,進而避免無法應答使用者請求。當然,此最大值不能超出“global”段中的定義。此外,需要留心的是,haproxy會為每個連接配接維持兩個緩沖,每個緩沖的大小為8KB,再加上其它的資料,每個連接配接将大約占用17KB的RAM空間。這意味着經過适當優化後,有着1GB的可用RAM空間時将能維護40000-50000并發連接配接。如果為<conns>指定了一個過大值,極端場景下,其最終占據的空間可能會超出目前主機的可用記憶體,這可能會帶來意想不到的結果;是以,将其設定了一個可接受值方為明智決定。其預設為2000。
7、default_backend
default_backend <backend>:在沒有比對的"use_backend"規則時為執行個體指定使用的預設後端,是以,其不可應用于backend區段。在"frontend"和"backend"之間進行内容交換時,通常使用"use-backend"定義其比對規則;而沒有被規則比對到的請求将由此參數指定的後端接收。
- <backend>:指定使用的後端的名稱;
使用案例:
use_backend dynamic if url_dyn
use_backend static if url_css url_img extension_img
default_backend dynamic
8、server
server <name> <address>[:port] [param*]:為後端聲明一個server,是以,不能用于defaults和frontend區段。
- <name>:為此伺服器指定的内部名稱,其将出現在日志及警告資訊中;如果設定了"http-send-server-name",它還将被添加至發往此伺服器的請求首部中;
- <address>:此伺服器的的IPv4位址,也支援使用可解析的主機名,隻不過在啟動時需要解析主機名至相應的IPv4位址;
- [:port]:指定将連接配接請求所發往的此伺服器時的目标端口,其為可選項;未設定時,将使用用戶端請求時的同一相端口;
- [param*]:為此伺服器設定的一系參數;其可用的參數非常多,具體請參考官方文檔中的說明,下面僅說明幾個常用的參數;
伺服器或預設伺服器參數:
- backup:設定為備用伺服器,僅在負載均衡場景中的其它server均不可用于啟用此server;
- check:啟動對此server執行健康狀态檢查,其可以借助于額外的其它參數完成更精細的設定,如:
- inter <delay>:設定健康狀态檢查的時間間隔,機關為毫秒,預設為2000;也可以使用fastinter和downinter來根據伺服器端狀态優化此時間延遲;
- rise <count>:設定健康狀态檢查中,某離線的server從離線狀态轉換至正常狀态需要成功檢查的次數;
- fall <count>:确認server從正常狀态轉換為不可用狀态需要檢查的次數;
- cookie <value>:為指定server設定cookie值,此處指定的值将在請求入站時被檢查,第一次為此值挑選的server将在後續的請求中被選中,其目的在于實作持久連接配接的功能;
- maxconn <maxconn>:指定此伺服器接受的最大并發連接配接數;如果發往此伺服器的連接配接數目高于此處指定的值,其将被放置于請求隊列,以等待其它連接配接被釋放;
- maxqueue <maxqueue>:設定請求隊列的最大長度;
- observe <mode>:通過觀察伺服器的通信狀況來判定其健康狀态,預設為禁用,其支援的類型有“layer4”和“layer7”,“layer7”僅能用于http代理場景;
- redir <prefix>:啟用重定向功能,将發往此伺服器的GET和HEAD請求均以302狀态碼響應;需要注意的是,在prefix後面不能使用/,且不能使用相對位址,以免造成循環;例如:
- server srv1 172.16.100.6:80 redir http://p_w_picpathserver.magedu.com check
- weight <weight>:權重,預設為1,最大值為256,0表示不參與負載均衡;
檢查方法:
option httpchk option httpchk <uri> option httpchk <method> <uri> option httpchk <method> <uri> <version>:不能用于frontend段,例如: backend https_relay mode tcp option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www.stu31.com server apache1 192.168.1.1:443 check port 80 |
server first 172.16.100.7:1080 cookie first check inter 1000 server second 172.16.100.8:1080 cookie second check inter 1000 |
9、capture request header
capture request header <name> len <length>:捕獲并記錄指定的請求首部最近一次出現時的第一個值,僅能用于“frontend”和“listen”區段。捕獲的首部值使用花括号{}括起來後添加進日志中。如果需要捕獲多個首部值,它們将以指定的次序出現在日志檔案中,并以豎線“|”作為分隔符。不存在的首部記錄為空字元串,最常需要捕獲的首部包括在虛拟主機環境中使用的“Host”、上傳請求首部中的“Content-length”、快速差別真實使用者和網絡機器人的“User-agent”,以及代理環境中記錄真實請求來源的“X-Forward-For”。
- <name>:要捕獲的首部的名稱,此名稱不區分字元大小寫,但建議與它們出現在首部中的格式相同,比如大寫首字母。需要注意的是,記錄在日志中的是首部對應的值,而非首部名稱。
- <length>:指定記錄首部值時所記錄的精确長度,超出的部分将會被忽略。
可以捕獲的請求首部的個數沒有限制,但每個捕獲最多隻能記錄64個字元。為了保證同一個frontend中日志格式的統一性,首部捕獲僅能在frontend中定義。
10、capture response header
capture response header <name> len <length>:捕獲并記錄響應首部,其格式和要點同請求首部。
11、stats enable
stats enable:啟用基于程式編譯時預設設定的統計報告,不能用于“frontend”區段。隻要沒有另外的其它設定,它們就會使用如下的配置:
- - stats uri : /haproxy?stats
- - stats realm : "HAProxy Statistics"
- - stats auth : no authentication
- - stats scope : no restriction
盡管“stats enable”一條就能夠啟用統計報告,但還是建議設定其它所有的參數,以免其依賴于預設設定而帶來非期後果。下面是一個配置案例。
backend public_www server websrv1 172.16.100.11:80 stats enable stats hide-version stats scope . stats uri /haproxyadmin?stats stats realm Haproxy\ Statistics stats auth statsadmin:password stats auth statsmaster:password |
12、stats hide-version
stats hide-version:啟用統計報告并隐藏HAProxy版本報告,不能用于“frontend”區段。預設情況下,統計頁面會顯示一些有用資訊,包括HAProxy的版本号,然而,向所有人公開HAProxy的精确版本号是非常有風險的,因為它能幫助惡意使用者快速定位版本的缺陷和漏洞。盡管“stats hide-version”一條就能夠啟用統計報告,但還是建議設定其它所有的參數,以免其依賴于預設設定而帶來非期後果。具體請參照“stats enable”一節的說明。
13、stats realm
stats realm <realm>:啟用統計報告并高精認證領域,不能用于“frontend”區段。haproxy在讀取realm時會将其視作一個單詞,是以,中間的任何空白字元都必須使用反斜線進行轉義。此參數僅在與“stats auth”配置使用時有意義。
- <realm>:實作HTTP基本認證時顯示在浏覽器中的領域名稱,用于提示使用者輸入一個使用者名和密碼。
盡管“stats realm”一條就能夠啟用統計報告,但還是建議設定其它所有的參數,以免其依賴于預設設定而帶來非期後果。具體請參照“stats enable”一節的說明。
14、stats scope
stats scope { <name> | "." }:啟用統計報告并限定報告的區段,不能用于“frontend”區段。當指定此語句時,統計報告将僅顯示其列舉出區段的報告資訊,所有其它區段的資訊将被隐藏。如果需要顯示多個區段的統計報告,此語句可以定義多次。需要注意的是,區段名稱檢測僅僅是以字元串比較的方式進行,它不會真檢測指定的區段是否真正存在。
- <name>:可以是一個“listen”、“frontend”或“backend”區段的名稱,而“.”則表示stats scope語句所定義的目前區段。
盡管“stats scope”一條就能夠啟用統計報告,但還是建議設定其它所有的參數,以免其依賴于預設設定而帶來非期後果。下面是一個配置案例。
backend private_monitoring
stats enable
stats uri /haproxyadmin?stats
stats refresh 10s
15、stats auth
stats auth <user>:<passwd>:啟用帶認證的統計報告功能并授權一個使用者帳号,其不能用于“frontend”區段。
- <user>:授權進行通路的使用者名;
- <passwd>:此使用者的通路密碼,明文格式;
此語句将基于預設設定啟用統計報告功能,并僅允許其定義的使用者通路,其也可以定義多次以授權多個使用者帳号。可以結合“stats realm”參數在提示使用者認證時給出一個領域說明資訊。在使用非法使用者通路統計功能時,其将會響應一個“401 Forbidden”頁面。其認證方式為HTTP Basic認證,密碼傳輸會以明文方式進行,是以,配置檔案中也使用明文方式存儲以說明其非保密資訊故此不能相同于其它關鍵性帳号的密碼。 盡管“stats auth”一條就能夠啟用統計報告,但還是建議設定其它所有的參數,以免其依賴于預設設定而帶來非期後果。
16 stats admin
stats admin { if | unless } <cond> :在指定的條件滿足時啟用統計報告頁面的管理級别功能,它允許通過web接口啟用或禁用伺服器,不過,基于安全的角度考慮,統計報告頁面應該盡可能為隻讀的。此外,如果啟用了HAProxy的多程序模式,啟用此管理級别将有可能導緻異常行為。 目前來說,POST請求方法被限制于僅能使用緩沖區減去保留部分之外的空間,是以,伺服器清單不能過長,否則,此請求将無法正常工作。是以,建議一次僅調整少數幾個伺服器。下面是兩個案例,第一個限制了僅能在本機打開報告頁面時啟用管理級别功能,第二個定義了僅允許通過認證的使用者使用管理級别功能。
應用舉例:
backend stats_localhost stats admin if LOCALHOST backend stats_auth stats auth haproxyadmin:password stats admin if TRUE |
17、 option httplog
option httplog [ clf ] :啟用記錄HTTP請求、會話狀态和計時器的功能。
- clf:使用CLF格式來代替HAProxy預設的HTTP格式,通常在使用僅支援CLF格式的特定日志分析器時才需要使用此格式。
預設情況下,日志輸入格式非常簡陋,因為其僅包括源位址、目标位址和執行個體名稱,而“option httplog”參數将會使得日志格式變得豐富許多,其通常包括但不限于HTTP請求、連接配接計時器、會話狀态、連接配接數、捕獲的首部及cookie、“frontend”、“backend”及伺服器名稱,當然也包括源位址和端口号等。
18、option logasap 、no option logasap
option logasap、no option logasap:啟用或禁用提前将HTTP請求記入日志,不能用于“backend”區段。
預設情況下,HTTP請求是在請求結束時進行記錄以便能将其整體傳輸時長和位元組數記入日志,由此,傳較大的對象時,其記入日志的時長可能會略有延遲。“option logasap”參數能夠在伺服器發送complete首部時即時記錄日志,隻不過,此時将不記錄整體傳輸時長和位元組數。此情形下,捕獲“Content-Length”響應首部來記錄傳輸的位元組數是一個較好選擇。下面是一個例子。
listen http_proxy 0.0.0.0:80 mode http option httplog option logasap log 172.16.100.9 local2 |
19、option forwardfor
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]:允許在發往伺服器的請求首部中插入“X-Forwarded-For”首部。
- <network>:可選參數,當指定時,源位址為比對至此網絡中的請求都禁用此功能。
- <name>:可選參數,可使用一個自定義的首部,如“X-Client”來替代“X-Forwarded-For”。有些獨特的web伺服器的确需要用于一個獨特的首部。
- if-none:僅在此首部不存在時才将其添加至請求封包問道中。
HAProxy工作于反向代理模式,其發往伺服器的請求中的用戶端IP均為HAProxy主機的位址而非真正用戶端的位址,這會使得伺服器端的日志資訊記錄不了真正的請求來源,“X-Forwarded-For”首部則可用于解決此問題。HAProxy可以向每個發往伺服器的請求上添加此首部,并以用戶端IP為其value。需要注意的是,HAProxy工作于隧道模式,其僅檢查每一個連接配接的第一個請求,是以,僅第一個請求封包被附加此首部。如果想為每一個請求都附加此首部,請確定同時使用了“option httpclose”、“option forceclose”和“option http-server-close”幾個option。
下面是一個例子。
frontend www mode http option forwardfor except 127.0.0.1 |
20、errorfile
errorfile <code> <file>:在使用者請求不存在的頁面時,傳回一個頁面檔案給用戶端而非由haproxy生成的錯誤代碼;可用于所有段中。
- <code>:指定對HTTP的哪些狀态碼傳回指定的頁面;這裡可用的狀态碼有200、400、403、408、500、502、503和504;
- <file>:指定用于響應的頁面檔案;
例如:
errorfile 400 /etc/haproxy/errorpages/400badreq.http errorfile 403 /etc/haproxy/errorpages/403forbid.http errorfile 503 /etc/haproxy/errorpages/503sorry.http |
21、errorloc 和 errorloc302
errorloc <code> <url>、errorloc302 <code> <url>:請求錯誤時,傳回一個HTTP重定向至某URL的資訊;可用于所有配置段中。
- <url>:Location首部中指定的頁面位置的具體路徑,可以是在目前伺服器上的頁面的相對路徑,也可以使用絕對路徑;需要注意的是,如果URI自身錯誤時産生某特定狀态碼資訊的話,有可能會導緻循環定向;
需要留意的是,這兩個關鍵字都會傳回302狀态嗎,這将使得用戶端使用同樣的HTTP方法擷取指定的URL,對于非GET法的場景(如POST)來說會産生問題,因為傳回客戶的URL是不允許使用GET以外的其它方法的。如果的确有這種問題,可以使用errorloc303來傳回303狀态碼給用戶端。
22、errorloc303
errorloc303 <code> <url>:請求錯誤時,傳回一個HTTP重定向至某URL的資訊給用戶端;可用于所有配置段中。
- <code>:指定對HTTP的哪些狀态碼傳回指定的頁面;這裡可用的狀态碼有400、403、408、500、502、503和504;
backend webserver server 172.16.100.6 172.16.100.6:80 check maxconn 3000 cookie srv01 server 172.16.100.7 172.16.100.7:80 check maxconn 3000 cookie srv02 errorloc 403 /etc/haproxy/errorpages/sorry.htm errorloc 503 /etc/haproxy/errorpages/sorry.htm |
四、配置案例
1、http伺服器配置示例
14 15 16 17 18 19 20 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 62 63 64 65 66 67 68 69 70 | #--------------------------------------------------------------------- # Global settings # to have these messages end up in /var/log/haproxy.log you will # need to: # # 1) configure syslog to accept network log events. This is done # by adding the '-r' option to the SYSLOGD_OPTIONS in # /etc/sysconfig/syslog # 2) configure local2 events to go to the /var/log/haproxy.log # file. A line like the following can be added to # /etc/sysconfig/syslog # local2.* /var/log/haproxy.log log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon 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 30000 listen stats bind 0.0.0.0:1080 stats auth admin:admin frontend http-in bind *:80 log global option httpclose option logasap option dontlognull capture request header Host len 20 capture request header Referer len 60 default_backend servers frontend healthcheck bind :1099 option forwardfor backend servers balance roundrobin server websrv1 192.168.10.11:80 check maxconn 2000 server websrv2 192.168.10.12:80 check maxconn 2000 |
2、負載均衡MySQL服務的配置示例
mode tcp maxconn 600 frontend mysql bind *:3306 default_backend mysqlservers backend mysqlservers balance leastconn server dbsrv1 192.168.10.11:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300 server dbsrv2 192.168.10.12:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300 |
五、ACL
1、ACL簡介
haproxy的ACL用于實作基于請求封包的首部、響應封包的内容或其它的環境狀态資訊來做出轉發決策,這大大增強了其配置彈性。其配置法則通常分為兩步,首先去定義ACL,即定義一個測試條件,而後在條件得到滿足時執行某特定的動作,如阻止請求或轉發至某特定的後端。
2、定義ACL的文法格式如下。
acl <aclname> <criterion> [flags] [operator] <value> ...
3、說明
- <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位址及網絡位址
同一個acl中可以指定多個測試條件,這些測試條件需要由邏輯操作符指定其關系。條件間的組合測試關系有三種:“與”(預設即為與操作)、“或”(使用“||”操作符)以及“非”(使用“!”操作符)。
4、 常用的測試标準(criteria)
- be_sess_rate <integer>
be_sess_rate(backend) <integer> :用于測試指定的backend上會話建立的速率(即每秒建立的會話數)是否滿足指定的條件;常用于在指定backend上的會話速率過高時将使用者請求轉發至另外的backend,或用于阻止攻擊行為。例如:
舉例:
backend dynamic mode http acl being_scanned be_sess_rate gt 50 redirect location /error_pages/denied.html if being_scanned |
- fe_sess_rate <integer>
fe_sess_rate(frontend) <integer>:用于測試指定的frontend(或目前frontend)上的會話建立速率是否滿足指定的條件;常用于為frontend指定一個合理的會話建立速率的上限以防止服務被濫用。例如下面的例子限定入站郵件速率不能大于50封/秒,所有在此指定範圍之外的請求都将被延時50毫秒。
frontend mail bind :25 mode tcp maxconn 500 acl too_fast fe_sess_rate ge 50 tcp-request inspect-delay 50ms tcp-request content accept if ! too_fast tcp-request content accept if WAIT_END |
- hdr <string>
hdr(header) <string>:用于測試請求封包中的所有首部或指定首部是否滿足指定的條件;指定首部時,其名稱不區分大小寫,且在括号“()”中不能有任何多餘的空白字元。測試伺服器端的響應封包時可以使用shdr()。例如下面的例子用于測試首部Connection的值是否為close。
舉例:hdr(Connection) -i close
- method <string>
method <string>:測試HTTP請求封包中使用的方法。
- path_beg <string>
path_beg <string>:用于測試請求的URL是否以<string>指定的模式開頭。下面的例子用于測試URL是否以/static、/p_w_picpaths、/javascript或/stylesheets頭。
舉例:acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheets
- path_end <string>
path_end <string>:用于測試請求的URL是否以<string>指定的模式結尾。例如,下面的例子使用者測試URL是否以jpg、gif、png、css或js結尾。
舉例:acl url_static path_end -i .jpg .gif .png .css .js
- hdr_beg <string>
hdr_beg <string>:用于測試請求封包的指定首部的開頭部分是否符合<string>指定的模式。例如,下面的例子用記測試請求是否為提供靜态内容的主機img、video、download或ftp。
舉例:acl host_static hdr_beg(host) -i img. video. download. ftp.
- hdr_end <string>
hdr_end <string>:用于測試請求封包的指定首部的結尾部分是否符合<string>指定的模式。例如,下面的例子用記測試請求是否為
動靜分離示例:
# turn on stats unix socket stats socket /var/lib/haproxy/stats acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheets acl url_static path_end -i .jpg .jpeg .gif .png .css .js use_backend static_servers if url_static default_backend dynamic_servers backend static_servers balance roundrobin server imgsrv1 172.16.200.7:80 check maxconn 6000 server imgsrv2 172.16.200.8:80 check maxconn 6000 backend dynamic_servers balance source server websrv1 172.16.200.7:80 check maxconn 1000 server websrv2 172.16.200.8:80 check maxconn 1000 server websrv3 172.16.200.9:80 check maxconn 1000 |
4、動靜分離示例
cookie srv insert nocache server websrv1 172.16.200.7:80 check maxconn 1000 cookie websrv1 server websrv2 172.16.200.8:80 check maxconn 1000 cookie websrv2 server websrv3 172.16.200.9:80 check maxconn 1000 cookie websrv3 |