HAProxy—— 3. 安裝配置

1. 安裝版本

1.1 centos7內置版本
 [root@master ~]# yum info haproxy
Loaded plugins: fastestmirror
Bad id for repo: centos-paas-openshift-origin , byte =   28
Loading mirror speeds from cached hostfile
Available Packages
Name        : haproxy
Arch        : x86_64
Version     : 1.5.18
Release     : 8.el7
Size        : 834 k
Repo        : source
Summary     : TCP/HTTP proxy and load balancer for high availability environments
URL         : http://www.haproxy.org/
License     : GPLv2+
Description : HAProxy is a TCP/HTTP reverse proxy which is particularly suited for high
            : availability environments. Indeed, it can:
            :  - route HTTP requests depending on statically assigned cookies
            :  - spread load among several servers while assuring server persistence
            :    through the use of HTTP cookies
            :  - switch to backup servers in the event a main server fails
            :  - accept connections to special ports dedicated to service monitoring
            :  - stop accepting connections without breaking existing ones
            :  - add, modify, and delete HTTP headers in both directions
            :  - block requests matching particular patterns
            :  - report detailed status to authenticated users from a URI
            :    intercepted by the application
1.2 華爲鏡像站點版本

在這裏插入圖片描述

2. 安裝

[root@master ~]# yum install haproxy
[root@master ~]#  rpm -ql haproxy
/etc/haproxy
/etc/haproxy/haproxy.cfg
/etc/logrotate.d/haproxy
/etc/sysconfig/haproxy 
/usr/bin/halog
/usr/bin/iprange
/usr/lib/systemd/system/haproxy.service
/usr/sbin/haproxy
/usr/sbin/haproxy-systemd-wrapper
/usr/share/doc/haproxy-1.5.18

3. 配置

haproxy 配置中分成五部分內容,分別如下:
global: 設置全局配置參數,屬於進程的配置,通常是和操作系統相關。
defaults:配置默認參數,這些參數可以被用到frontend,backend,Listen組件;
frontend:接收請求的前端虛擬節點,Frontend可以更加規則直接指定具體使用後端的backend;
backend:後端服務集羣的配置,是真實服務器,一個Backend對應一個或者多個實體服務器;
Listen :frontend和backend的組合體。

3.1 全局配置
3.1.1 進程管理及安全相關的參數
chroot <jail dir>:修改haproxy的工作目錄至指定的目錄並在放棄權限之前執行chroot()操作,可以提升haproxy的安全級別,不過需要注意的是要確保指定的目錄爲空目錄且任何用戶均不能有寫權限。
– daemon:讓haproxy以守護進程的方式工作於後臺,其等同於“-D”選項的功能,當然,也可以在命令行中以“-db”選項將其禁用。
– pidfile
– gid <number>:以指定的GID運行haproxy,建議使用專用於運行haproxy的GID,以免因權限問題帶來風險。
– group <group name>:同gid,不過指定的組名。
– uid:以指定的UID身份運行haproxy進程
– user:同uid,但使用的是用戶名。
– log <address> <facility> [max level [min level]]:定義全局的syslog服務器,最多可以定義兩個。
– log-send-hostname [<string>]:在syslog信息的首部添加當前主機名,可以爲“string”指定的名稱,也可以缺省使用當前主機名。
– nbproc <number>:指定啓動的haproxy進程的個數,只能用於守護進程模式的haproxy;默認只啓動一個進程,鑑於調試困難等多方面的原因,一般只在單進程僅能打開少數文件描述符的場景中才使用多進程模式。
– ulimit-n:設定每進程所能夠打開的最大文件描述符數目,默認情況下其會自動進行計算,因此不推薦修改此選項;Linux默認單進程打開文件數爲1024個。
– stats:用戶訪問統計數據的接口
– node:定義當前節點的名稱,用於HA場景中多haproxy進程共享同一個IP地址時。
– description:當前實例的描述信息
3.1.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.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
3.1.3 Debug相關的參數
- debug 
- quiet
3.1.4 超時時長

timeout http request :在客戶端建立連接但不請求數據時,關閉客戶端連接。
timeout queue :等待最大時長
timeout connect: 定義haproxy將客戶端請求轉發至後端服務器所等待的超時時長
timeout client:客戶端非活動狀態的超時時長
timeout server:客戶端與服務器端建立連接後,等待服務器端的超時時長。
timeout http-keep-alive :定義保持連接的超時時長
timeout check:健康狀態監測時的超時時間,過短會誤判,過長資源消耗。
maxconn :每個server最大的連接數
http-server-close : 在使用長連接時,爲了避免客戶端超時沒有關閉長連接,此功能可以使服務器端關閉長連接。
redispatch: 在使用基於cookie定向時,一旦後端某一server宕機時,會將會話重新定向至某一上游服務器,必須使用 的選項。

3.1.5 實現訪問控制:

http-request: 7層過濾
tcp-request content: tcp層過濾,四層過濾

3.2 關鍵字參考

3.2.1 balance

balance [ ] balance url_param [check_post []]
定義負載均衡算法,可用於“defaults”、“listen”和“backend”。用於在負載均衡場景中挑選一個server,其僅應用於持久信息不可用的條件下或需要將一個連接重新派發至另一個服務器時。支持的算法有:
roundrobin:基於權重進行輪叫,在服務器的處理時間保持均勻分佈時,這是最平衡、最公平的算法。此算法是動態的,這表示其權重可以在運行時進行調整,不過,在設計上,每個後端服務器僅能最多接受4128個連接;並支持慢啓動。
static-rr:基於權重進行輪叫,與roundrobin類似,但是爲靜態方法,在運行時調整其服務器權重不會生效;不過,其在後端服務器連接數上沒有限制;不支持慢啓動,在高負荷的情況下,服務器重新上線時會立即被分配大量連接。
leastconn(WLC):適用於長連接的會話,新的連接請求被派發至具有最少連接數目的後端服務器;在有着較長時間會話的場景中推薦使用此算法,如LDAP、SQL等,其並不太適用於較短會話的應用層協議,如HTTP;此算法是動態的,可以在運行時調整其權重。
source:將請求的源地址進行hash運算,並由後端服務器的權重總數相除後派發至某匹配的服務器;這可以使得同一個客戶端IP的請求始終被派發至某特定的服務器;不過,當服務器權重總數發生變化時,如某服務器宕機或添加了新的服務器,許多客戶端的請求可能會被派發至與此前請求不同的服務器;常用於負載均衡無cookie功能的基於TCP的協議;其默認爲靜態,不過也可以使用hash-type修改此特性;
對原地址hash,第一次調度時使用WLC。 source:IP層,位於同一個NAT服務器背後的多個請求都會定向至同一個upstream
server,不利於負載均衡,一般只有不支持使用cookie插入又需要保持會話時使用 cookie:應用層,有更好的負載均衡效果;
hash/weight%ip :除以權重取模
uri:對URI的左半部分(“問題”標記之前的部分)或整個URI進行hash運算,並由服務器的總權重相除後派發至某匹配的服務器;這可以使得對同一個URI的請求總是被派發至某特定的服務器,除非服務器的權重總數發生了變化;此算法常用於代理緩存或反病毒代理以提高緩存的命中率;需要注意的是,此算法僅應用於HTTP後端服務器場景;其默認爲靜態算法,不過也可以使用hash-type修改此特性;
url_param:通過爲URL指定的參數在每個HTTP
GET請求中將會被檢索;如果找到了指定的參數且其通過等於號“=”被賦予了一個值,那麼此值將被執行hash運算並被服務器的總權重相除後派發至某匹配的服務器;此算法可以通過追蹤請求中的用戶標識進而確保同一個用戶ID的請求將被送往同一個特定的服務器,除非服務器的總權重發生了變化;如果某請求中沒有出現指定的參數或其沒有有效值,則使用輪叫算法對相應請求進行調度;此算法默認爲靜態的,不過其也可以使用hash-type修改此特性;
hdr():對於每個HTTP請求,通過指定的HTTP首部將會被檢索;如果相應的首部沒有出現或其沒有有效值,則使用輪叫算法對相應請求進行調度;其有一個可選選項“use_domain_only”,可在指定檢索類似Host類的首部時僅計算域名部分(比如通過www.feiyu.com來說,僅計算feiyu字符串的hash值)以降低hash算法的運算量;此算法默認爲靜態的,不過其也可以使用hash-type修改此特性;
rdp-cookie(name) 表示根據據cookie(name)來鎖定並哈希每一次TCP請求。

3.2.2 bind

bind [

]:<port_range> [, …] bind [
]:<port_range> [,
…] interface 此指令僅能用於frontend和listen區段,用於定義一個或幾個監聽的套接字。

:可選選項,其可以爲主機名、IPv4地址、IPv6地址或*;省略此選項、將其指定爲*或0.0.0.0時,將監聽當前系統的所有IPv4地址;:可以是一個特定的TCP端口,也可是一個端口範圍(如5005-5010),代理服務器將通過指定的端口來接收客戶端請求;需要注意的是,每組監聽的套接字在同一個實例上只能使用一次,而且小於1024的端口需要有特定權限的用戶才能使用,這可能需要通過uid參數來定義;:指定物理接口的名稱,僅能在Linux系統上使用;其不能使用接口別名,而僅能使用物理接口名稱,而且只有管理有權限指定綁定的物理接口;

3.2.3 mode

mode { tcp|http|health }
設定實例的運行模式或協議。當實現內容交換時,前端和後端必須工作於同一種模式(一般說來都是HTTP模式),否則將無法啓動實例。
tcp:實例運行於純TCP模式,在客戶端和服務器端之間將建立一個全雙工的連接,且不會對7層報文做任何類型的檢查;通常用於SSL、SSH、SMTP等應用;
http:實例運行於HTTP模式,客戶端請求在轉發至後端服務器之前將被深度分析,所有不與RFC格式兼容的請求都會被拒絕;此爲默認模式;
health:實例工作於health模式,其對入站請求僅響應“OK”信息並關閉連接,且不會記錄任何日誌信息;此模式將用於響應外部組件的健康狀態檢查請求;目前來講,此模式已經廢棄,因爲tcp或http模式中的monitor關鍵字可完成類似功能。

3.2.4 hash-type hash-type 定義用於將hash碼映射至後端服務器的方法;其不能用於frontend區段;可用方法有map-based和consistent,在大多數場景下推薦使用默認的map-based方法。
map-based:hash表是一個包含了所有在線服務器的靜態數組。其hash值將會非常平滑,會將權重考慮在列,但其爲靜態方法,對在線服務器的權重進行調整將不會生效,這意味着其不支持慢速啓動。此外,挑選服務器是根據其在數組中的
位置進行的,因此,當一臺服務器宕機或添加了一臺新的服務器時,大多數連接將會被重新派發至一個與此前不同的服務器上,對於緩存服務器的工作場景來說,此方法不甚適用。
consistent:“一致性哈希算法”,hash表是一個由各服務器填充而成的樹狀結構,將服務器散列在hash環上;基於hash鍵在hash樹中查找相應的服務器時,最近的服務器將被選中。此方法是動態的,支持在運行時修改服務器權重,因此兼
容慢速啓動的特性。添加一個新的服務器時,僅會對一小部分請求產生影響,因此,尤其適用於後端服務器爲cache的場景。不過,此算法不甚平滑,派發至各服務器的請求未必能達到理想的均衡效果,因此,可能需要不時的調整服務器的權重以獲得更好的均衡性。

3.2.5 log

log global log

[ []]
爲每個實例啓用事件和流量日誌,因此可用於所有區段。每個實例最多可以指定兩個log參數,不過,如果使用了“log
global”且”global”段已經定了兩個log參數時,多餘了log參數將被忽略。
global:當前實例的日誌系統參數同”global”段中的定義時,將使用此格式;每個實例僅能定義一次“log
global”語句,且其沒有任何額外參數;

:定義日誌發往的位置,其格式之一可以爲,其中的port爲UDP協議端口,默認爲514;格式之二爲Unix套接字文件路徑,但需要留心chroot應用及用戶的讀寫權限; :可以爲syslog系統的標準facility之一; :定義日誌級別,即輸出信息過濾器,默認爲所有信息;指定級別時,所有等於或高於此級別的日誌信息將會被髮送;

3.2.6 maxconn

maxconn
設定一個前端的最大併發連接數,因此,其不能用於backend區段。對於大型站點來說,可以儘可能提高此值以便讓haproxy管理連接隊列,從而避免無法應答用戶請求。當然,此最大值不能超出“global”段中的定義。此外,需要留心的是,haproxy會爲每個連接維持兩個緩衝,每個緩衝的大小爲8KB,再加上其它的數據,每個連接將大約佔用17KB的RAM空間。這意味着經過適當優化後,有着1GB的可用RAM空間時將能維護40000-50000併發連接。
如果爲指定了一個過大值,極端場景下,其最終佔據的空間可能會超出當前主機的可用內存,這可能會帶來意想不到的結果;因此,將其設定了一個可接受值方爲明智決定。其默認爲2000。

3.2.7 default_backend

default_backend
在沒有匹配的”use_backend”規則時爲實例指定使用的默認後端,因此,其不可應用於backend區段。在”frontend”和”backend”之間進行內容交換時,通常使用”use-backend”定義其匹配規則;而沒有被規則匹配到的請求將由此參數指定的後端接收。
:指定使用的後端的名稱; 使用案例: use_backend dynamic if url_dyn use_backend
static if url_css url_img extension_img default_backend dynamic

3.2.8 server

server

[:port] [param*]
爲後端聲明一個server,因此,不能用於defaults和frontend區段。
:爲此服務器指定的內部名稱,其將出現在日誌及警告信息中;如果設定了”http-send-server-name”,它還將被添加至發往此服務器的請求首部中;

:此服務器的的IPv4地址,也支持使用可解析的主機名,只不過在啓動時需要解析主機名至相應的IPv4地址; [:port]:指定將連接請求所發往的此服務器時的目標端口,其爲可選項;未設定時,將使用客戶端請求時的同一相端口; [param*]:爲此服務器設定的一系參數;其可用的參數非常多,具體請參考官方文檔中的說明,下面僅說明幾個常用的參數; 服務器或默認服務器參數: backup:設定爲備用服務器,僅在負載均衡場景中的其它server均不可用於啓用此server; check:啓動對此server執行健康狀態檢查,其可以藉助於額外的其它參數完成更精細的設定,如: inter :設定健康狀態檢查的時間間隔,單位爲毫秒,默認爲2000;也可以使用fastinter和downinter來根據服務器端狀態優化此時間延遲; rise :設定健康狀態檢查中,某離線的server從離線狀態轉換至正常狀態需要成功檢查的次數; fall :確認server從正常狀態轉換爲不可用狀態需要檢查的次數; cookie :爲指定server設定cookie值,此處指定的值將在請求入站時被檢查,第一次爲此值挑選的server將在後續的請求中被選中,其目的在於實現持久連接的功能; maxconn :指定此服務器接受的最大併發連接數;如果發往此服務器的連接數目高於此處指定的值,其將被放置於請求隊列,以等待其它連接被釋放; haproxy 有n個進程,每個支持m個連接,後端有x個服務器,每個最大支持y個連接,則 n*m <= x*y,如果後端服務器支持排隊,則n*m <= x*(y+z),z爲每個服務器的排隊隊列 maxqueue :設定請求隊列的最大長度; observe :通過觀察服務器的通信狀況來判定其健康狀態,默認爲禁用,其支持的類型有“layer4”和“layer7”,“layer7”僅能用於http代理場景; redir :啓用重定向功能,將發往此服務器的GET和HEAD請求均以302狀態碼響應;需要注意的是,在prefix後面不能使用/,且不能使用相對地址,以免造成循環;例如: server srv1 172.16.100.6:80 redir http://imageserver.feiyu.com check 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

3.2.9 capture request header

capture request header len
捕獲並記錄指定的請求首部最近一次出現時的第一個值,僅能用於“frontend”和“listen”區段。捕獲的首部值使用花括號{}括起來後添加進日誌中。如果需要捕獲多個首部值,它們將以指定的次序出現在日誌文件中,並以豎線“|”作爲分隔符。不存在的首部記錄爲空字符串,最常需要捕獲的首部包括在虛擬主機環境中使用的“Host”、上傳請求首部中的“Content-length”、快速區別真實用戶和網絡機器人的“User-agent”,以及代理環境中記錄真實請求來源的“X-Forward-For”。
:要捕獲的首部的名稱,此名稱不區分字符大小寫,但建議與它們出現在首部中的格式相同,比如大寫首字母。需要注意的是,記錄在日誌中的是首部對應的值,而非首部名稱。
:指定記錄首部值時所記錄的精確長度,超出的部分將會被忽略。
可以捕獲的請求首部的個數沒有限制,但每個捕獲最多隻能記錄64個字符。爲了保證同一個frontend中日誌格式的統一性,首部捕獲僅能在frontend中定義。

3.2.10 capture response header

capture response header len 捕獲並記錄響應首部,其格式和要點同請求首部。

3.2.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

3.2.12 stats hide-version

啓用統計報告並隱藏HAProxy版本報告,不能用於“frontend”區段。默認情況下,統計頁面會顯示一些有用信息,包括HAProxy的版本號,然而,向所有人公開HAProxy的精確版本號是非常有風險的,因爲它能幫助惡意用戶快速定位版本的缺陷和漏洞。儘管“stats
hide-version”一條就能夠啓用統計報告,但還是建議設定其它所有的參數,以免其依賴於默認設定而帶來非期後果。具體請參照“stats
enable”一節的說明。

3.2.13 stats realm

stats realm
啓用統計報告並高精認證領域,不能用於“frontend”區段。haproxy在讀取realm時會將其視作一個單詞,因此,中間的任何空白字符都必須使用反斜線進行轉義。此參數僅在與“stats
auth”配置使用時有意義。 :實現HTTP基本認證時顯示在瀏覽器中的領域名稱,用於提示用戶輸入一個用戶名和密碼。
儘管“stats
realm”一條就能夠啓用統計報告,但還是建議設定其它所有的參數,以免其依賴於默認設定而帶來非期後果。具體請參照“stats
enable”一節的說明。

3.2.14 stats scope

stats scope { | “.” }
啓用統計報告並限定報告的區段,不能用於“frontend”區段。當指定此語句時,統計報告將僅顯示其列舉出區段的報告信息,所有其它區段的信息將被隱藏。如果需要顯示多個區段的統計報告,此語句可以定義多次。需要注意的是,區段名稱檢測僅僅是以字符串比較的方式進行,它不會真檢測指定的區段是否真正存在。
:可以是一個“listen”、“frontend”或“backend”區段的名稱,而“.”則表示stats
scope語句所定義的當前區段。 儘管“stats
scope”一條就能夠啓用統計報告,但還是建議設定其它所有的參數,以免其依賴於默認設定而帶來非期後果。下面是一個配置案例。 backend
private_monitoring stats enable stats uri /haproxyadmin?stats stats
refresh 10s

3.2.15 stats auth

stats auth : 啓用帶認證的統計報告功能並授權一個用戶帳號,其不能用於“frontend”區段。
:授權進行訪問的用戶名; :此用戶的訪問密碼,明文格式;
此語句將基於默認設定啓用統計報告功能,並僅允許其定義的用戶訪問,其也可以定義多次以授權多個用戶帳號。可以結合“stats
realm”參數在提示用戶認證時給出一個領域說明信息。在使用非法用戶訪問統計功能時,其將會響應一個“401
Forbidden”頁面。其認證方式爲HTTP
Basic認證,密碼傳輸會以明文方式進行,因此,配置文件中也使用明文方式存儲以說明其非保密信息故此不能相同於其它關鍵性帳號的密碼。
儘管“stats auth”一條就能夠啓用統計報告,但還是建議設定其它所有的參數,以免其依賴於默認設定而帶來非期後果。

3.2.16 stats admin

stats admin { if | unless }
在指定的條件滿足時啓用統計報告頁面的管理級別功能,它允許通過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

3.2.17 option httplog

option httplog [ clf ] 啓用記錄HTTP請求、會話狀態和計時器的功能。
clf:使用CLF格式來代替HAProxy默認的HTTP格式,通常在使用僅支持CLF格式的特定日誌分析器時才需要使用此格式。
默認情況下,日誌輸入格式非常簡陋,因爲其僅包括源地址、目標地址和實例名稱,而“option
httplog”參數將會使得日誌格式變得豐富許多,其通常包括但不限於HTTP請求、連接計時器、會話狀態、連接數、捕獲的首部及cookie、“frontend”、“backend”及服務器名稱,當然也包括源地址和端口號等。

3.2.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

3.2.19 option forwardfor

option forwardfor [ except ] [ header ] [ if-none ]
允許在發往服務器的請求首部中插入“X-Forwarded-For”首部。
:可選參數,當指定時,源地址爲匹配至此網絡中的請求都禁用此功能。
:可選參數,可使用一個自定義的首部,如“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

3.2.20 errorfile

errorfile
在用戶請求不存在的頁面時,返回一個頁面文件給客戶端而非由haproxy生成的錯誤代碼;可用於所有段中。
:指定對HTTP的哪些狀態碼返回指定的頁面;這裏可用的狀態碼有200、400、403、408、500、502、503和504;
:指定用於響應的頁面文件; 例如: errorfile 400
/etc/haproxy/errorpages/400badreq.http errorfile 403
/etc/haproxy/errorpages/403forbid.http errorfile 503
/etc/haproxy/errorpages/503sorry.http

3.2.21 errorloc 和 errorloc302

errorloc errorloc302
請求錯誤時,返回一個HTTP重定向至某URL的信息;可用於所有配置段中。
:指定對HTTP的哪些狀態碼返回指定的頁面;這裏可用的狀態碼有200、400、403、408、500、502、503和504;
:Location首部中指定的頁面位置的具體路徑,可以是在當前服務器上的頁面的相對路徑,也可以使用絕對路徑;需要注意的是,如果URI自身錯誤時產生某特定狀態碼信息的話,有可能會導致循環定向;
需要留意的是,這兩個關鍵字都會返回302狀態嗎,這將使得客戶端使用同樣的HTTP方法獲取指定的URL,對於非GET法的場景(如POST)來說會產生問題,因爲返回客戶的URL是不允許使用GET以外的其它方法的。如果的確有這種問題,可以使用errorloc303來返回303狀態碼給客戶端。

3.2.22 errorloc303

errorloc303 請求錯誤時,返回一個HTTP重定向至某URL的信息給客戶端;可用於所有配置段中。
:指定對HTTP的哪些狀態碼返回指定的頁面;這裏可用的狀態碼有400、403、408、500、502、503和504;
: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

3.3 ACL

haproxy的ACL用於實現基於請求報文的首部、響應報文的內容或其它的環境狀態信息來做出轉發決策,這大大增強了其配置彈性。其配置法則通常分爲兩步,首先去定義ACL,即定義一個測試條件,而後在條件得到滿足時執行某特定的動作,如阻止請求或轉發至某特定的後端。
acl [flags] [operator] …
:ACL名稱,區分字符大小寫,且其只能包含大小寫字母、數字、-(連接線)、_(下劃線)、.(點號)和:(冒號);haproxy中,acl可以重名,這可以把多個測試條件定義爲一個共同的acl;
:測試標準,即對什麼信息發起測試;測試方式可以由[flags]指定的標誌進行調整;而有些測試標準也可以需要爲其在之前指定一個操作符[operator];
[flags]:目前haproxy的acl支持的標誌位有3個:
-i:不區分中模式字符的大小寫;
-f:從指定的文件中加載模式;
–:標誌符的強制結束標記,在模式中的字符串像標記符時使用; :acl測試條件支持的值有以下四類: 整數或整數範圍:如1024:65535表示從1024至65535;僅支持使用正整數(如果出現類似小數的標識,其爲通常爲版本測試),且支持使用的操作符有5個,分別爲eq、ge、gt、le和lt;
字符串:支持使用“-i”以忽略字符大小寫,支持使用“\”進行轉義;如果在模式首部出現了-i,可以在其之前使用“–”標誌位;
正則表達式:其機制類同字符串匹配; IP地址及網絡地址;
同一個acl中可以指定多個測試條件,這些測試條件需要由邏輯操作符指定其關係。條件間的組合測試關係有三種:“與”(默認即爲與操作)、“或”(使用“||”操作符)以及“非”(使用“!”操作符)。

3.3.1 常用的測試標準(criteria)

be_sess_rate be_sess_rate(backend)
用於測試指定的backend上會話創建的速率(即每秒創建的會話數)是否滿足指定的條件;常用於在指定backend上的會話速率過高時將用戶請求轉發至另外的backend,或用於阻止攻擊行爲。例如:
backend dynamic mode http acl being_scanned be_sess_rate gt 50
redirect location /error_pages/denied.html if being_scanned

3.3.2 fe_sess_rate

fe_sess_rate(frontend)
用於測試指定的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

3.3.3 hdr

hdr(header)
用於測試請求報文中的所有首部或指定首部是否滿足指定的條件;指定首部時,其名稱不區分大小寫,且在括號“()”中不能有任何多餘的空白字符。測試服務器端的響應報文時可以使用shdr()。例如下面的例子用於測試首部Connection的值是否爲close。
hdr(Connection) -i close

3.3.4 method

method 測試HTTP請求報文中使用的方法。

3.3.5 path_beg

用於測試請求的URL是否以指定的模式開頭。下面的例子用於測試URL是否以/static、/images、/javascript或/stylesheets頭。
acl url_static path_beg -i /static /images /javascript /stylesheets

3.3.6 path_end

用於測試請求的URL是否以指定的模式結尾。例如,下面的例子用戶測試URL是否以jpg、gif、png、css或js結尾。
acl url_static path_end -i .jpg .gif .png .css .js

3.3.7 hdr_beg

用於測試請求報文的指定首部的開頭部分是否符合指定的模式。例如,下面的例子用記測試請求是否爲提供靜態內容的主機img、video、download或ftp。
acl host_static hdr_beg(host) -i img. video. download. ftp.

3.3.8 hdr_end

用於測試請求報文的指定首部的結尾部分是否符合指定的模式。

4.配置示例

4.1
global   # 全局參數的設置
    log 127.0.0.1 local0 info
    # log語法:log <address_1>[max_level_1] # 全局的日誌配置,使用log關鍵字,指定使用127.0.0.1上的syslog服務中的local0日誌設備,記錄日誌等級爲info的日誌
    user haproxy
    group haproxy
    # 設置運行haproxy的用戶和組,也可使用uid,gid關鍵字替代之
    daemon
    # 以守護進程的方式運行
    nbproc 16
    # 設置haproxy啓動時的進程數,根據官方文檔的解釋,我將其理解爲:該值的設置應該和服務器的CPU核心數一致,即常見的2顆8核心CPU的服務器,即共有16核心,則可以將其值設置爲:<=16 ,創建多個進程數,可以減少每個進程的任務隊列,但是過多的進程數也可能會導致進程的崩潰。這裏我設置爲16
    maxconn 4096
    # 定義每個haproxy進程的最大連接數 ,由於每個連接包括一個客戶端和一個服務器端,所以單個進程的TCP會話最大數目將是該值的兩倍。
    #ulimit -n 65536
    # 設置最大打開的文件描述符數,在1.4的官方文檔中提示,該值會自動計算,所以不建議進行設置
    pidfile /var/run/haproxy.pid
    # 定義haproxy的pid 
defaults # 默認部分的定義
    mode http
    # mode語法:mode {http|tcp|health} 。http是七層模式,tcp是四層模式,health是健康檢測,返回OK
    log 127.0.0.1 local3 err
    # 使用127.0.0.1上的syslog服務的local3設備記錄錯誤信息
    retries 3
    # 定義連接後端服務器的失敗重連次數,連接失敗次數超過此值後將會將對應後端服務器標記爲不可用
    option httplog
    # 啓用日誌記錄HTTP請求,默認haproxy日誌記錄是不記錄HTTP請求的,只記錄“時間[Jan 5 13:23:46] 日誌服務器[127.0.0.1] 實例名已經pid[haproxy[25218]] 信息[Proxy http_80_in stopped.]”,日誌格式很簡單。
    option redispatch
    # 當使用了cookie時,haproxy將會將其請求的後端服務器的serverID插入到cookie中,以保證會話的SESSION持久性;而此時,如果後端的服務器宕掉了,但是客戶端的cookie是不會刷新的,如果設置此參數,將會將客戶的請求強制定向到另外一個後端server上,以保證服務的正常。
    option abortonclose
    # 當服務器負載很高的時候,自動結束掉當前隊列處理比較久的鏈接
    option dontlognull
    # 啓用該項,日誌中將不會記錄空連接。所謂空連接就是在上游的負載均衡器或者監控系統爲了探測該服務是否存活可用時,需要定期的連接或者獲取某一固定的組件或頁面,或者探測掃描端口是否在監聽或開放等動作被稱爲空連接;官方文檔中標註,如果該服務上游沒有其他的負載均衡器的話,建議不要使用該參數,因爲互聯網上的惡意掃描或其他動作就不會被記錄下來
    option httpclose
    # 這個參數我是這樣理解的:使用該參數,每處理完一個request時,haproxy都會去檢查http頭中的Connection的值,如果該值不是close,haproxy將會將其刪除,如果該值爲空將會添加爲:Connection: close。使每個客戶端和服務器端在完成一次傳輸後都會主動關閉TCP連接。與該參數類似的另外一個參數是“option forceclose”,該參數的作用是強制關閉對外的服務通道,因爲有的服務器端收到Connection: close時,也不會自動關閉TCP連接,如果客戶端也不關閉,連接就會一直處於打開,直到超時。
    contimeout 5000
    # 設置成功連接到一臺服務器的最長等待時間,默認單位是毫秒,新版本的haproxy使用timeout connect替代,該參數向後兼容
    clitimeout 3000
    # 設置連接客戶端發送數據時的成功連接最長等待時間,默認單位是毫秒,新版本haproxy使用timeout client替代。該參數向後兼容
    srvtimeout 3000
    # 設置服務器端迴應客戶度數據發送的最長等待時間,默認單位是毫秒,新版本haproxy使用timeout server替代。該參數向後兼容
 
listen status # 定義一個名爲status的部分
    bind 0.0.0.0:1080
    # 定義監聽的套接字
    mode http
    # 定義爲HTTP模式
    log global
    # 繼承global中log的定義
    stats refresh 30s
    # stats是haproxy的一個統計頁面的套接字,該參數設置統計頁面的刷新間隔爲30s
    stats uri /admin?stats
    # 設置統計頁面的uri爲/admin?stats
    stats realm Private lands
    # 設置統計頁面認證時的提示內容
    stats auth admin:password
    # 設置統計頁面認證的用戶和密碼,如果要設置多個,另起一行寫入即可
    stats hide-version
    # 隱藏統計頁面上的haproxy版本信息
 
frontend http_80_in # 定義一個名爲http_80_in的前端部分
    bind 0.0.0.0:80
    # http_80_in定義前端部分監聽的套接字
    mode http
    # 定義爲HTTP模式
    log global
    # 繼承global中log的定義
    option forwardfor
    # 啓用X-Forwarded-For,在requests頭部插入客戶端IP發送給後端的server,使後端server獲取到客戶端的真實IP
    acl static_down nbsrv(static_server) lt 1
    # 定義一個名叫static_down的acl,當backend static_sever中存活機器數小於1時會被匹配到
    acl php_web url_reg /*.php$
    #acl php_web path_end .php
    # 定義一個名叫php_web的acl,當請求的url末尾是以.php結尾的,將會被匹配到,上面兩種寫法任選其一
    acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$
    #acl static_web path_end .gif .png .jpg .css .js .jpeg
    # 定義一個名叫static_web的acl,當請求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif結尾的,將會被匹配到,上面兩種寫法任選其一
    use_backend php_server if static_down
    # 如果滿足策略static_down時,就將請求交予backend php_server
    use_backend php_server if php_web
    # 如果滿足策略php_web時,就將請求交予backend php_server
    use_backend static_server if static_web
    # 如果滿足策略static_web時,就將請求交予backend static_server
 
backend php_server #定義一個名爲php_server的後端部分
    mode http
    # 設置爲http模式
    balance source
    # 設置haproxy的調度算法爲源地址hash
    cookie SERVERID
    # 允許向cookie插入SERVERID,每臺服務器的SERVERID可在下面使用cookie關鍵字定義
    option httpchk GET /test/index.php
    # 開啓對後端服務器的健康檢測,通過GET /test/index.php來判斷後端服務器的健康情況
    server php_server_1 10.12.25.68:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2
    server php_server_2 10.12.25.72:80 cookie 2 check inter 2000 rise 3 fall 3 weight 1
    server php_server_bak 10.12.25.79:80 cookie 3 check inter 1500 rise 3 fall 3 backup
    # server語法:server [:port] [param*] # 使用server關鍵字來設置後端服務器;爲後端服務器所設置的內部名稱[php_server_1],該名稱將會呈現在日誌或警報中、後端服務器的IP地址,支持端口映射[10.12.25.68:80]、指定該服務器的SERVERID爲1[cookie 1]、接受健康監測[check]、監測的間隔時長,單位毫秒[inter 2000]、監測正常多少次後被認爲後端服務器是可用的[rise 3]、監測失敗多少次後被認爲後端服務器是不可用的[fall 3]、分發的權重[weight 2]、最後爲備份用的後端服務器,當正常的服務器全部都宕機後,纔會啓用備份服務器[backup]
 
backend static_server
    mode http
    option httpchk GET /test/index.html
    server static_server_1 10.12.25.83:80 cookie 3 check inter 2000 rise 3 fall 3
4.2 定義獨立日誌文件
[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端中添加此行 
4.3 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
4.4 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
4.5 動靜分離示例:
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_<a href="http://www.ttlsa.com/php/" title="php"target="_blank">php</a> 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
4.6 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
4.7 負載均衡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 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon

defaults
mode tcp
log global
option httplog
option dontlognull
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 600

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 mysql
bind *:3306
mode tcp
log global
default_backend mysqlservers

backend mysqlservers
balance leastconn
server dbsrv1 192.168.1.111:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300
server dbsrv2 192.168.1.112:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300

————Blueicex 2020/03/26 16:19 [email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章