haproxy配置詳解

1 HAproxy介紹
1.1 Haproxy是一個開源的高性能的反向代理或者說是負載均衡服務軟件之一,它支持雙機熱備、虛擬主機、基於TCP和HTTP應用代理等功能。其配置簡單,並且擁有很好的對服務器節點的健康檢查功能(至關於keepalived健康檢查),當其代理的後端服務器出現故障時,Haproxy會自動的將該故障服務器摘除,當服務器的故障恢復後Haproxy還會自動將RS服務器上線
1.2 Haproxy特別適用與那些訪問量很大。但又須要會話保持或七層應用的業務。Haproxy運行在普通的服務器硬件上,僅僅進行簡單的優化就能夠支持數以萬計的併發鏈接。而且它的運行模式使得它能夠很簡單安全的整合到各類網站的架構中,同時使得應用服務器不會暴露到網絡中
1.3 HAProxy 實現了一種事件驅動、單一進程模型,此模型支持很是大的併發鏈接數。多進程或多線程模型受內存限制 、系統調度器限制以及無處不在的鎖限制,不多能處理數千併發鏈接。事件驅動模型由於在有更好的資源和時間管理的用戶端(User-Space) 實現全部這些任務,因此沒有這些問題。此模型的弊端是,在多核系統上,這些程序一般擴展性較差。這就是爲何他們必須進行優化以 使每一個CPU時間片(Cycle)作更多的工做
1.4 HAProxy 支持鏈接拒絕 : 由於維護一個鏈接的打開的開銷是很低的,有時咱們很須要限制***蠕蟲(attack bots),也就是說限制它們的鏈接打開從而限制它們的危害。 這個已經爲一個陷於小型DDoS***的網站開發了並且已經拯救了不少站點,這個優勢也是其它負載均衡器沒有的
1.5 HAProxy 支持全透明代理(已具有硬件防火牆的典型特色): 能夠用客戶端IP地址或者任何其餘地址來鏈接後端服務器. 這個特性僅在Linux 2.4/2.6內核打了cttproxy補丁後纔可使用. 這個特性也使得爲某特殊服務器處理部分流量同時又不修改服務器的地址成爲可能
1.6 Haproxy軟件引入了frontend,backend的功能,frontend(acl規則匹配)能夠運維管理人員根據任意HTTP請求頭作規則匹配,而後把請求定向到相關的backend(server pools等待前端把請求轉過來的服務器組)。經過frontend和backup,咱們能夠很容易的實現haproxy的7層代理功能,haproxy是一款不可多得的優秀代理服務軟件
1.7 Haproxy支持兩種主要代理模式:第一個是4層tcp代理(例如:可用於郵件服務內部協議通訊服務器、Mysql服務等)。第二個是7層代理(如HTTP代理)。在4層tcp代理模式下,Haproxy僅在客戶端和服務器之間雙向轉發流量。可是在7層模式下Haproxy會分析應用層協議,而且能經過運行、拒絕、交換、增長、修改或者刪除請求(request)或者回應(reponse)裏指定內容來控制協議javascript

2 Haproxy解決方案拓撲圖
2.1 Haproxy L4負載均衡應用架構拓撲
Haproxy軟件的四層tcp代理應用很是優秀,配置很是簡單方便,比LVS和Nginx要方便不少,由於不須要在RS端執行腳本便可實現應用代理。
說明:因爲Haproxy採用的是NAT模式,數據包來去都會通過Haproxy,所以,在流量特別大的狀況下,其性能不如LVS。
在通常的中小型公司,建議採用haproxy作負載均衡,而不要使用LVS或者Nginx。
所謂的四層就是ISO參考模型中的第四層。四層負載均衡也稱爲四層交換機,它主要是經過分析IP層及TCP/UDP層的流量實現的基於IP加端口的負載均衡。常見的基於四層的負載均衡器有LVS、F5等。
以常見的TCP應用爲例,負載均衡器在接收到第一個來自客戶端的SYN請求時,會經過設定的負載均衡算法選擇一個最佳的後端服務器,同時將報文中目標IP地址修改成後端服務器IP,而後直接轉發給該後端服務器,這樣一個負載均衡請求就完成了。從這個過程來看,一個TCP鏈接是客戶端和服務器直接創建的,而負載均衡器只不過完成了一個相似路由器的轉發動做。在某些負載均衡策略中,爲保證後端服務器返回的報文能夠正確傳遞給負載均衡器,在轉發報文的同時可能還會對報文原來的源地址進行修改。整個過程下圖所示php

2.2 Haproxy L7負載均衡應用架構拓撲
Haproxy軟件的最大優勢在於其7層的根據URL請求頭應用過濾的功能,通常用在LVS軟件的下一層,或者像官方推薦的能夠掛在硬件負載均衡NS、F5下使用
七層負載均衡器也稱爲七層交換機,位於OSI的最高層,即應用層,此時負載均衡器支持多種應用協議,常見的有HTTP、FTP、SMTP等。七層負載均衡器能夠根據報文內容,再配合負載均衡算法來選擇後端服務器,所以也稱爲「內容交換器」。好比,對於Web服務器的負載均衡,七層負載均衡器不但能夠根據「IP+端口」的方式進行負載分流,還能夠根據網站的URL、訪問域名、瀏覽器類別、語言等決定負載均衡的策略。例如,有兩臺Web服務器分別對應中英文兩個網站,兩個域名分別是A、B,要實現訪問A域名時進入中文網站,訪問B域名時進入英文網站,這在四層負載均衡器中幾乎是沒法實現的,而七層負載均衡能夠根據客戶端訪問域名的不一樣選擇對應的網頁進行負載均衡處理。常見的七層負載均衡器有HAproxy、Nginx等。
這裏仍以常見的TCP應用爲例,因爲負載均衡器要獲取到報文的內容,所以只能先代替後端服務器和客戶端創建鏈接,接着,才能收到客戶端發送過來的報文內容,而後再根據該報文中特定字段加上負載均衡器中設置的負載均衡算法來決定最終選擇的內部服務器。縱觀整個過程,七層負載均衡器在這種狀況下相似於一個代理服務器。整個過程以下圖所示css

對比四層負載均衡和七層負載均衡運行的整個過程,能夠看出,在七層負載均衡模式下,負載均衡器與客戶端及後端的服務器會分別創建一次TCP鏈接,而在四層負載均衡模式下,僅創建一次TCP鏈接。由此可知,七層負載均衡對負載均衡設備的要求更高,而七層負載均衡的處理能力也必然低於四層模式的負載均衡html

3 安裝haproxy
3.1 yum -y install haproxy
rpm -qi haproxy (版本爲1.5.4)
rpm -ql haproxy
/etc/haproxy
/etc/haproxy/haproxy.cfg(haproxy的配置文件)
/etc/logrotate.d/haproxy
/etc/sysconfig/haproxy
3.2 詳細的配置文件
haproxy配置文件分爲兩部分組成:全局設定和代理的設定,共分爲五段:obal,default,frontend,backend,listen
3.2.1 配置文件格式
haproxy的配置處理3類主要參數來源:
最優先處理的命令行參數
"global"配置段,用於設定全局配置參數
proxy相關配置段,如「default」、「listen」、「frontend」和「backend」
3.2.2 時間格式
一些包含了值的參數表示時間,如超長時間。這些值通常以毫秒爲單位,但也可使用其餘的時間單位後綴
us: 微秒(microseconds),即1/1000000秒;
ms: 毫秒(milliseconds),即1/1000秒;
s: 秒(seconds);
m: 分鐘(minutes);
h:小時(hours);
d: 天(days);
3.2.3 全局的配置
進程管理及安全相關的參數前端

  • chroot <jail dir>:修改haproxy的工做目錄至指定的目錄並在放棄權限以前執行chroot()操做,能夠提高haproxy的安全級別,不過須要注意的是肯定指定的目錄爲空目錄且任何用戶均不能有寫權限;
  • daemon:讓haproxy以守護進程的方式工做與後臺,其等同與「-D」選項的功能
  • 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:
  • uid:以指定的UID身份運行haproxy
  • ulimit-n:設定每一個進程可以打開的最大文件描述符數目,默認狀況下其會自動進行計算,所以不推薦修改此選項;Linux默認單進程打開的文件數爲1024個
  • user:同uid,但使用的是用戶名
  • stats:用戶訪問統計數據的接口
  • node:定義當前節點的名稱,用於HA場景中多haproxy進程共享同一個ip地址時;
  • description:當前實例的描述的信息

性能調整相關的參數
– 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.25-28系列的內核上,tcp重組功能有bug存在;
– spread-checks <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.client <number>:
– tune.rcvbuf.server <number>:設定內核套接字中服務端或客戶端接收緩衝的大小,單位爲字節;強烈推薦使用默認值;
– tune.sndbuf.client:
– tune.sndbuf.server:java

Debug相關的參數node

  • debug
  • quiet

超時時長
timeout http request :在客戶端創建鏈接但不請求數據時,關閉客戶端鏈接
timeout queue :等待最大時長
timeout connect: 定義haproxy將客戶端請求轉發至後端服務器所等待的超時時長
timeout client:客戶端非活動狀態的超時時長
timeout server:客戶端與服務器端創建鏈接後,等待服務器端的超時時長,
timeout http-keep-alive :定義保持鏈接的超時時長
timeout check:健康狀態監測時的超時時間,太短會誤判,過長資源消耗
maxconn :每一個server最大的鏈接數mysql

http-server-close : 在使用長鏈接時,爲了不客戶端超時沒有關閉長鏈接,此功能可使服務器端關閉長鏈接
redispatch: 在使用基於cookie定向時,一旦後端某一server宕機時,會將會話從新定向至某一上游服務器,必須使用 的選項web

實現訪問控制
http-request:7層過濾
tcp-request content:tcp層過濾,四層過濾
3.2.4 代理
代理相關的配置能夠以下配置段中正則表達式

  • defaults <name>
  • frontend <name>
  • backend <name>
    「defaults」段用於爲全部其餘配置段提供默認參數,這配置默認配置參數可由下一個「defaults」所從新設定
    「frontend」段用於定義一系列監聽的套接字,這些套接字可接受客戶端請求並與之創建鏈接
    「backend」段用於定義一系列「後端」服務器,代理將會對應客戶端的請求轉發至這些服務器
    「listen」段經過關聯「frontend」和「backend」定義了一個完整的代理,一般只對TCP流量有用
    全部代理的名稱只能使用大寫字母、小寫字母、數字、-(中劃線)、_(下劃線)、.(點號)和:(冒號)。此外,ACL名稱會區分大小寫
    4 配置文件中關鍵字參考
    4.1 balance
    balance [ ]
    balance url_param [check_post []]
    定義負載均衡算法,可用於「defaults」、「listen」和「backend」。用於在負載均衡場景中挑選一個server,其僅應用於持久信息不可用的條件下或須要將一個鏈接從新派發至另外一個服務器時。支持的算法有:
    4.1.1 roundrobin:基於權重進行輪詢,在服務器的處理時間保持均勻分佈時,這是最平衡、最公平的算法。此算法是動態的,這表示其權重能夠在運行時進行調整,不過,在設計上,每一個後端服務器僅能最多接受4128個鏈接;並支持慢啓動
    4.1.2 static-rr:基於權重進行輪詢,與roundrobin相似,可是爲靜態方法,在運行時調整其服務器權重不會生效;不過,其在後端服務器鏈接數上沒有限制;不支持慢啓動,在高負荷的狀況下,服務器從新上線時會當即被分配大量鏈接
    4.1.3 leastconn(WLC):適用於長鏈接的會話,新的鏈接請求被派發至具備最少鏈接數目的後端服務器;在有着較長時間會話的場景中推薦使用此算法,如LDAP、SQL等,其並不太適用於較短會話的應用層協議,如HTTP;此算法是動態的,能夠在運行時調整其權重;
    4.1.4 source:將請求的源地址進行hash運算,並由後端服務器的權重總數相除後派發至某匹配的服務器;這可使得同一個客戶端IP的請求始終被派發至某特定的服務器;不過,當服務器權重總數發生變化時,如某服務器宕機或添加了新的服務器,許多客戶端的請求可能會被派發至與此前請求不一樣的服務器;經常使用於負載均衡無cookie功能的基於TCP的協議;其默認爲靜態,不過也可使用hash-type修改此特性;
    1)對原地址hash,第一次調度時使用WLC
    source:IP層,位於同一個NAT服務器背後的多個請求都會定向至同一個upstream server,不利於負載均衡,通常只有不支持使用cookie插入又須要保持會話時使用cookie,應用層,有更好的負載均衡效果
    2)hash/weight%ip :除以權重取模
    4.1.5 uri:對URI的左半部分(「問題」標記以前的部分)或整個URI進行hash運算,並由服務器的總權重相除後派發至某匹配的服務器;這可使得對同一個URI的請求老是被派發至某特定的服務器,除非服務器的權重總數發生了變化;此算法經常使用於代理緩存或反病毒代理以提升緩存的命中率;須要注意的是,此算法僅應用於HTTP後端服務器場景;其默認爲靜態算法,不過也可使用hash-type修改此特性
    4.1.6 url_param:經過<argument>爲URL指定的參數在每一個HTTP GET請求中將會被檢索;若是找到了指定的參數且其經過等於號「=」被賦予了一個值,那麼此值將被執行hash運算並被服務器的總權重相除後派發至某匹配的服務器;此算法能夠經過追蹤請求中的用戶標識進而確保同一個用戶ID的請求將被送往同一個特定的服務器,除非服務器的總權重發生了變化;若是某請求中沒有出現指定的參數或其沒有有效值,則使用輪叫算法對相應請求進行調度;此算法默認爲靜態的,不過其也可使用hash-type修改此特性
    4.1.7 hdr(<name>):對於每一個HTTP請求,經過<name>指定的HTTP首部將會被檢索;若是相應的首部沒有出現或其沒有有效值,則使用輪叫算法對相應請求進行調度;其有一個可選選項「use_domain_only」,可在指定檢索相似Host類的首部時僅計算域名部分(好比經過www.feiyu.com來講,僅計算feiyu字符串的hash值)以下降hash算法的運算量;此算法默認爲靜態的,不過其也可使用hash-type修改此特性
    4.1.8 rdp-cookie(name):表示根據據cookie(name)來鎖定並哈希每一次TCP請求
    4.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系統上使用;其不能使用接口別名,而僅能使用物理接口名稱,並且只有管理有權限指定綁定的物理接口
    4.3 mode
    mode { tcp|http|health }
    設定實例的運行模式或協議。當實現內容交換時,前端和後端必須工做於同一種模式(通常說來都是HTTP模式),不然將沒法啓動實例。
    tcp:實例運行於純TCP模式,在客戶端和服務器端之間將創建一個全雙工的鏈接,且不會對7層報文作任何類型的檢查;一般用於SSL、SSH、SMTP等應用;
    http:實例運行於HTTP模式,客戶端請求在轉發至後端服務器以前將被深度分析,全部不與RFC格式兼容的請求都會被拒絕;此爲默認模式;
    health:實例工做於health模式,其對入站請求僅響應「OK」信息並關閉鏈接,且不會記錄任何日誌信息;此模式將用於響應外部組件的健康狀態檢查請求;目前來說,此模式已經廢棄,由於tcp或http模式中的monitor關鍵字可完成相似功能
    4.4 hast-type
    hash-type <method>
    定義用於將hash碼映射至後端服務器的方法;其不能用於frontend區段;可用方法有map-based和consistent,在大多數場景下推薦使用默認的map-based方法。
    map-based:hash表是一個包含了全部在線服務器的靜態數組。其hash值將會很是平滑,會將權重考慮在列,但其爲靜態方法,對在線服務器的權重進行調整將不會生效,這意味着其不支持慢速啓動。此外,挑選服務器是根據其在數組中的位置進行的,所以,當一臺服務器宕機或添加了一臺新的服務器時,大多數鏈接將會被從新派發至一個與此前不一樣的服務器上,對於緩存服務器的工做場景來講,此方法不甚適用。
    consistent:「一致性哈希算法」,hash表是一個由各服務器填充而成的樹狀結構,將服務器散列在hash環上;基於hash鍵在hash樹中查找相應的服務器時,最近的服務器將被選中。此方法是動態的,支持在運行時修改服務器權重,所以兼容慢速啓動的特性。添加一個新的服務器時,僅會對一小部分請求產生影響,所以,尤爲適用於後端服務器爲cache的場景。不過,此算法不甚平滑,派發至各服務器的請求未必能達到理想的均衡效果,所以,可能須要不時的調整服務器的權
    重以得到更好的均衡性
    4.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>:定義日誌級別,即輸出信息過濾器,默認爲全部信息;指定級別時,全部等於或高於此級別的日誌信息將會被髮送;
    4.6 maxcon
    maxconn <conns>
    設定一個前端的最大併發鏈接數,所以,其不能用於backend區段。對於大型站點來講,能夠儘量提升此值以便讓haproxy管理鏈接隊列,從而避免沒法應答用戶請求。固然,此最大值不能超出「global」段中的定義。此外,須要留心的是,haproxy會爲每一個鏈接維持兩個緩衝,每一個緩衝的大小爲8KB,再加上其它的數據,每一個鏈接將大約佔用17KB的RAM空間。這意味着通過適當優化後,有着1GB的可用RAM空間時將能維護40000-50000併發鏈接。
    若是爲<conns>指定了一個過大值,極端場景下,其最終佔據的空間可能會超出當前主機的可用內存,這可能會帶來意想不到的結果;所以,將其設定了一個可接受值方爲明智決定。其默認爲2000
    4.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
    4.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從正常狀態轉換爲不可用狀態須要檢查的次數;

The default
values are the following ones :

  • inter : 2000 意思是不加該參數,正常狀況默認沒兩秒檢查一次
  • rise : 2 意思是不加該參數,在RS宕機後恢復前,檢查2次OK,認爲其復活,並加入到羣組中
  • fall : 3 意思是不加該參數,檢查3此後,認爲RS宕機,剔除集羣組
  • port : default server port 不加該參數,默認就是端口檢查
  • addr : specific address for the test (default = address server)

cookie <value>:爲指定server設定cookie值,此處指定的值將在請求入站時被檢查,第一次爲此值挑選的server將在後續的請求中被選中,其目的在於實現持久鏈接的功能;
maxconn <maxconn>:指定此服務器接受的最大併發鏈接數;若是發往此服務器的鏈接數目高於此處指定的值,其將被放置於請求隊列,以等待其它鏈接被釋放;
haproxy 有n個進程,每一個支持m個鏈接,後端有x個服務器,每一個最大支持y個鏈接,則 nm <= xy,若是後端服務器支持排隊,則nm <= x(y+z),z爲每一個服務器的排隊隊列
maxqueue <maxqueue>:設定請求隊列的最大長度;
observe <mode>:經過觀察服務器的通訊情況來斷定其健康狀態,默認爲禁用,其支持的類型有「layer4」和「layer7」,「layer7」僅能用於http代理場景;
redir <prefix>:啓用重定向功能,將發往此服務器的GET和HEAD請求均以302狀態碼響應;須要注意的是,在prefix後面不能使用/,且不能使用相對地址,以避免形成循環;例如:
server srv1 172.16.100.6:80 redir http://imageserver.feiyu.com check
weight <weight>:權重,默認爲1,最大值爲256,0表示不參與負載均衡(不被調度);
檢查方法:
option httpchk
option httpchk
option httpchk
option httpchk :不能用於frontend段,例如:
backend https_relay
mode tcp
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www.feiyu.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
4.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中定義
4.10 capture request header
capture response header <name> len <length>
捕獲並記錄響應首部,其格式和要點同請求首部
4.11 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
    4.12 stats hide-version
    stats hide-version
    啓用統計報告並隱藏HAProxy版本報告,不能用於「frontend」區段。默認狀況下,統計頁面會顯示一些有用信息,包括HAProxy的版本號,然而,向全部人公開HAProxy的精確版本號是很是有風險的,由於它能幫助惡意用戶快速定位版本的缺陷和漏洞。儘管「stats hide-version」一條就可以啓用統計報告,但仍是建議設定其它全部的參數,以避免其依賴於默認設定而帶來非期後果。具體請參照「stats enable」一節的說明
    4.13 stats realm
    stats realm <realm>
    啓用統計報告並高精認證領域,不能用於「frontend」區段。haproxy在讀取realm時會將其視做一個單詞,所以,中間的任何空白字符都必須使用反斜線進行轉義。此參數僅在與「stats auth」配置使用時有意義。
    <realm>:實現HTTP基本認證時顯示在瀏覽器中的領域名稱,用於提示用戶輸入一個用戶名和密碼。
    儘管「stats realm」一條就可以啓用統計報告,但仍是建議設定其它全部的參數,以避免其依賴於默認設定而帶來非期後果。具體請參照「stats enable」一節的說明
    4.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
    4.15 stats auth
    stats auth <user>:<passwd>
    啓用帶認證的統計報告功能並受權一個用戶賬號,其不能用於「frontend」區段。
    <user>:受權進行訪問的用戶名;
    <passwd>:此用戶的訪問密碼,明文格式;
    此語句將基於默認設定啓用統計報告功能,並僅容許其定義的用戶訪問,其也能夠定義屢次以受權多個用戶賬號。能夠結合「stats realm」參數在提示用戶認證時給出一個領域說明信息。在使用非法用戶訪問統計功能時,其將會響應一個「401 Forbidden」頁面。其認證方式爲HTTP Basic認證,密碼傳輸會以明文方式進行,所以,配置文件中也使用明文方式存儲以說明其非保密信息故此不能相同於其它關鍵性賬號的密碼。
    儘管「stats auth」一條就可以啓用統計報告,但仍是建議設定其它全部的參數,以避免其依賴於默認設定而帶來非期後果
    4.16 stats admin
    stats admin { if | unless } <cond>
    在指定的條件知足時啓用統計報告頁面的管理級別功能,它容許經過web接口啓用或禁用服務器,不過,基於安全的角度考慮,統計報告頁面應該儘量爲只讀的。此外,若是啓用了HAProxy的多進程模式,啓用此管理級別將有可能致使異常行爲。
    目前來講,POST請求方法被限制於僅能使用緩衝區減去保留部分以外的空間,所以,服務器列表不能過長,不然,此請求將沒法正常工做。所以,建議一次僅調整少數幾個服務器。下面是兩個案例,第一個限制了僅能在本機打開報告頁面時啓用管理級別功能,第二個定義了僅容許經過認證的用戶使用管理級別功能
    backend stats_localhost
    stats enable
    stats admin if LOCALHOST
    backend stats_auth
    stats enable
    stats auth haproxyadmin:password
    stats admin if TRUE
    4.17 option httplog
    option httplog [clf]
    啓用記錄HTTP請求、會話狀態和計時器的功能。
    clf:使用CLF格式來代替HAProxy默認的HTTP格式,一般在使用僅支持CLF格式的特定日誌分析器時才須要使用此格式。
    默認狀況下,日誌輸入格式很是簡陋,由於其僅包括源地址、目標地址和實例名稱,而「option httplog」參數將會使得日誌格式變得豐富許多,其一般包括但不限於HTTP請求、鏈接計時器、會話狀態、鏈接數、捕獲的首部及cookie、「frontend」、「backend」及服務器名稱,固然也包括源地址和端口號等
    4.18 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
    4.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
    4.20 errorfile
    errorfile <code> <file>
    在用戶請求不存在的頁面時,返回一個頁面文件給客戶端而非由haproxy生成的錯誤代碼;可用於全部段中。
    <code>:指定對HTTP的哪些狀態碼返回指定的頁面;這裏可用的狀態碼有200、400、40三、40八、500、50二、503和504;
    <file>:指定用於響應的頁面文件;
    例如
    errorfile 400 /etc/haproxy/errorpages/400badreq.http
    errorfile 403 /etc/haproxy/errorpages/403forbid.http
    errorfile 503 /etc/haproxy/errorpages/503sorry.http
    4.21 errorloc和errorloc32
    errorloc <code> <url>
    errorloc302 <code> <url>
    請求錯誤時,返回一個HTTP重定向至某URL的信息;可用於全部配置段中。
    <code>:指定對HTTP的哪些狀態碼返回指定的頁面;這裏可用的狀態碼有200、400、40三、40八、500、50二、503和504;
    <url>:Location首部中指定的頁面位置的具體路徑,能夠是在當前服務器上的頁面的相對路徑,也可使用絕對路徑;須要注意的是,若是URI自身錯誤時產生某特定狀態碼信息的話,有可能會致使循環定向;
    須要留意的是,這兩個關鍵字都會返回302狀態嗎,這將使得客戶端使用一樣的HTTP方法獲取指定的URL,對於非GET法的場景(如POST)來講會產生問題,由於返回客戶的URL是不容許使用GET之外的其它方法的。若是的確有這種問題,可使用errorloc303來返回303狀態碼給客戶端
    4.22 errorloc303
    errorloc303 <code><url>
    請求錯誤時,返回一個HTTP重定向至某URL的信息給客戶端;可用於全部配置段中。
    <code>:指定對HTTP的哪些狀態碼返回指定的頁面;這裏可用的狀態碼有400、40三、40八、500、50二、503和504;
    <url>:Location首部中指定的頁面位置的具體路徑,能夠是在當前服務器上的頁面的相對路徑,也可使用絕對路徑;須要注意的是,若是URI自身錯誤時產生某特定狀態碼信息的話,有可能會致使循環定向
    例如:
    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

5 ACL
haproxy的ACL用於實現基於請求報文的首部、響應報文的內容或其它的環境狀態信息來作出轉發決策,這大大加強了其配置彈性。其配置法則一般分爲兩步,首先去定義ACL,即定義一個測試條件,然後在條件獲得知足時執行某特定的動做,如阻止請求或轉發至某特定的後端。定義ACL的語法格式以下。
acl <aclname> <criterion> [flags] [operator] <value> ...
<aclname>:ACL名稱,區分字符大小寫,且其只能包含大小寫字母、數字、-(鏈接線)、_(下劃線)、.(點號)和:(冒號);haproxy中,acl能夠重名,這能夠把多個測試條件定義爲一個共同的acl;
<criterion>:測試標準,即對什麼信息發起測試;測試方式能夠由[flags]指定的標誌進行調整;而有些測試標準也能夠須要爲其在以前指定一個操做符[operator];
[flags]:目前haproxy的acl支持的標誌位有3個:
-i:不區分中模式字符的大小寫;
-f:從指定的文件中加載模式;
--:標誌符的強制結束標記,在模式中的字符串像標記符時使用;
<value>:acl測試條件支持的值有如下四類:
整數或整數範圍:如1024:65535表示從1024至65535;僅支持使用正整數(若是出現相似小數的標識,其爲一般爲版本測試),且支持使用的操做符有5個,分別爲eq、ge、gt、le和lt;
字符串:支持使用「-i」以忽略字符大小寫,支持使用「\」進行轉義;若是在模式首部出現了-i,能夠在其以前使用「–」標誌位;
正則表達式:其機制類同字符串匹配;
IP地址及網絡地址;
同一個acl中能夠指定多個測試條件,這些測試條件須要由邏輯操做符指定其關係。條件間的組合測試關係有三種:「與」(默認即爲與操做)、「或」(使用「||」操做符)以及「非」(使用「!」操做符)
5.1 經常使用的測試標準(criteria)
5.1.1 be_sess_rate
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
5.1.2 fe_sess_rate
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
5.1.3 hdr<string>
hdr(header)<string>
用於測試請求報文中的全部首部或指定首部是否知足指定的條件;指定首部時,其名稱不區分大小寫,且在括號「()」中不能有任何多餘的空白字符。測試服務器端的響應報文時可使用shdr()。例以下面的例子用於測試首部Connection的值是否爲close
hdr(connection) -i close
5.1.4 method <string>
method<string>
測試HTTP請求報文中使用的方法
5.1.5 path_beg <string>
用於測試請求的URL是否以指定的模式開頭。下面的例子用於測試URL是否以/static、/images、/javascript或/stylesheets頭
acl url_static path_beg -i /static /images /javascript /stylesheets
5.1.6 path_end <string>
用於測試請求的URL是否以<string>指定的模式結尾。例如,下面的例子用戶測試URL是否以jpg、gif、png、css或js結尾
acl url_static path_end -i .jpg .gif .png .css .js
5.1.7 hdr_beg <string>
用於測試請求報文的指定首部的結尾部分是否符合<string>指定的模式
6 配置案例
前端調度器IP:192.168.1.210
後端應用服務器IP: 192.168.1.111 和 192.168.1.112
定義獨立日誌文件
[root@node1 haproxy]# vim /etc/rsyslog.conf #爲其添加日誌功能

Provides UDP syslog reception

$ModLoad imudp
$UDPServerRun 514 ------>啓動udp,啓動端口後將做爲服務器工做

Provides TCP syslog reception

$ModLoad imtcp
$InputTCPServerRun 514 ------>啓動tcp監聽端口
local2.* /var/log/haproxy.log

[root@node1 haproxy]# service rsyslog restar
[root@LB haproxy]# vim haproxy.cfg
log 127.0.0.1 local2 --------->在global端中添加此行

一個最簡單的http服務的配置
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
frontend webser #webser爲名稱
option forwardfor
bind :80
default_backend app
backend app
balance roundrobin #使擁roundrobin 算法
server app1 192.168.1.111:80 check
server app2 192.168.1.112:80 check
haproxy統計頁面的輸出機制
frontend webser
log 127.0.0.1 local3
option forwardfor
bind
:80
default_backend app
backend app
cookie node insert nocache
balance roundrobin
server app1 192.168.1.111:80 check cookie node1 intval 2 rise 1 fall 2
server app2 192.168.1.112:80 check cookie node2 intval 2 rise 1 fall 2
server backup 127.0.0.1:8010 check backup
listen statistics
bind :8009 # 自定義監聽端口
stats enable # 啓用基於程序編譯時默認設置的統計報告
stats auth admin:admin # 統計頁面用戶名和密碼設置
stats uri /admin?stats # 自定義統計頁面的URL,默認爲/haproxy?stats
stats hide-version # 隱藏統計頁面上HAProxy的版本信息
stats refresh 30s # 統計頁面自動刷新時間
stats admin if TRUE #若是認證經過就作管理功能,能夠管理後端的服務器
stats realm Hapadmin # 統計頁面密碼框上提示文本,默認爲Haproxy\ Statistics
動靜分離示例
frontend webservs
bind
:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js .html
acl url_php path_end -i .php
acl host_static hdr_beg(host) -i img. imgs. video. videos. ftp. image. download.
use_backend static if url_static or host_static
use_backend dynamic if url_php
default_backend dynamic
backend static
balance roundrobin
server node1 192.168.1.111:80 check maxconn 3000
backend dynamic
balance roundrobin
server node2 192.168.1.112:80 check maxconn 1000
http服務器配置完整示例
#---------------------------------------------------------------------

Global settings

#---------------------------------------------------------------------
global

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
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 #記錄請求首部的前20個字符
capture request header Referer len 60 #referer跳轉引用,就是上一級
default_backend servers
frontend healthcheck
bind :1099 #定義外部檢測機制
mode http
option httpclose
option forwardfor
default_backend servers
backend servers
balance roundrobin
server websrv1 192.168.1.111:80 check maxconn 2000
server websrv2 192.168.1.112:80 check maxconn 2000
負載均衡MySQL服務的配置示例
#---------------------------------------------------------------------

Global settings

#---------------------------------------------------------------------
global

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 local2chroot /var/lib/haproxypidfile /var/run/haproxy.pidmaxconn 4000user haproxygroup haproxydaemondefaultsmode tcplog globaloption httplogoption dontlognullretries 3timeout http-request 10stimeout queue 1mtimeout connect 10stimeout client 1mtimeout server 1mtimeout http-keep-alive 10stimeout check 10smaxconn 600listen statsmode httpbind 0.0.0.0:1080stats enablestats hide-versionstats uri /haproxyadmin?statsstats realm Haproxy\ Statisticsstats auth admin:adminstats admin if TRUEfrontend mysqlbind *:3306mode tcplog globaldefault_backend mysqlserversbackend mysqlserversbalance leastconnserver dbsrv1 192.168.1.111:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300server dbsrv2 192.168.1.112:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300

相關文章
相關標籤/搜索