本文目錄:1.1 配置文件說明1.2 簡單配置示例1.3 全局配置參數1.4. proxy配置段和常用配置選項 1.4.1 http事務模型相關設置 1.4.2 balance 1.4.3 hash-type 1.4.4 bind 1.4.5 mode 1.4.6 log 1.4.7 capture ...
本文目錄:
1.1 配置文件說明
1.2 簡單配置示例
1.3 全局配置參數
1.4. proxy配置段和常用配置選項
1.4.1 http事務模型相關設置
1.4.2 balance
1.4.3 hash-type
1.4.4 bind
1.4.5 mode
1.4.6 log
1.4.7 capture request header 和 capture response header
1.4.8 maxconn
1.4.9 use_backend
1.4.10 default_backend
1.4.11 server和default-server
1.4.12 option httpcheck
1.4.13 stats相關
1.4.14 option forwardfor
1.4.15 錯誤頁面相關
1.4.16 cookie和redispatch
1.4.17 reqadd和rspadd
1.4.18 超時時間相關
1.4.19 http協議過濾:http-request
1.4.20 tcp請求和響應過濾
1.5 ACL
1.5.1 ACL語法
1.5.2 ACL實現動靜分離示例
haproxy幾乎每個大版本都提供了官方手冊(內容幾乎都相同),手冊非常詳細。例如haproxy 1.7版本關於配置文件的官方手冊:http://cbonte.github.io/haproxy-dconv/1.7/configuration.html。
haproxy的靈魂在於配置文件,配置文件重點在於前端(frontend)和後端(backend)的定製。全局選項(global)的配置將預設提供的稍微修改下即可。
可以使用haproxy命令行檢查配置文件語法是否正確。
haproxy -f /etc/haproxy/phaproxy.cfg -c
或者使用sysv腳本的check參數。
service haproxy check
1.1 配置文件說明
HAProxy在啟動之前會解析配置文件,有3處配置信息來源:
- 最優先處理來自haproxy命令行給出的參數。
- "global"配置段的參數,設定為全局參數。
- 代理配置段。包括
defaults
,listen
,frontend
和backend
段。
另外haproxy配置文件引入了引號和轉義符:反斜線表示轉義符;單引號表示強引用;雙引號表示弱引用。如果字元串內需要輸入空格,則空格需要進行轉義或者通過引號包圍,不轉義時在配置文件中表示分隔符。
如:
\ 標記一個空白字元以區分它的本義和用作分隔符時的空白符
\# to mark a hash and differentiate it from a comment
\\ to use a backslash
\' to use a single quote and differentiate it from strong quoting
\" to use a double quote and differentiate it from weak quoting
下麵幾種情況是等價的:
log-format %{+Q}o\ %t\ %s\ %{-Q}r
log-format "%{+Q}o %t %s %{-Q}r"
log-format '%{+Q}o %t %s %{-Q}r'
log-format "%{+Q}o %t"' %s %{-Q}r'
log-format "%{+Q}o %t"' %s'\ %{-Q}r
在配置文件中,一些包含了數值的參數表示時間,如timeout。這些值預設以毫秒為單位,但也可以使用其它的時間單位尾碼。
- us: 微秒(microseconds),即1/1000000秒;
- ms: 毫秒(milliseconds),即1/1000秒;
- s: 秒(seconds);
- m: 分鐘(minutes);
- h:小時(hours);
- d: 天(days);
1.2 簡單配置示例
以下是一個簡單的配置文件,該配置文件代理模式為http,frontend定義的是監聽在前端所有網卡的80埠上,此文件中只定義了一個後端伺服器組backend,該backend只包含一臺監聽在127.0.0.1:8000的伺服器。在haproxy的術語中,frontend表示的是監聽套接字,用於等待客戶端的連接。
global
daemon
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:80
default_backend web_servers
backend web_servers
server server1 127.0.0.1:8000 maxconn 32
如果使用listen配置方式替換backend和frontend,則更簡單,以下是等價配置:
global
daemon
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen http-in
bind *:80
server server1 127.0.0.1:8000 maxconn 32
1.3 全局配置參數
全局配置參數設定haproxy進程運行環境,一般和操作系統指定的值有關,配置正確後一般都不會去修改。全局配置參數一般都有對應的命令行選項。
1.進程管理及安全相關的參數。
haproxy是單進程、事件驅動、非阻塞模型的調度器。雖然是單進程,但官方強烈建議不要設置為多進程,因為單進程可以處理很多個代理連接請求且性能極好(官方手冊說30W個代理實例都能良好運行),設置為多進程反而有一些限制。
- chroot :修改haproxy工作目錄至指定目錄,可提升haproxy安全級別,但要確保必須為空且任何用戶均不能有寫許可權;
- daemon:讓haproxy以守護進程的方式工作於後臺,等同於命令行的"-D"選項,當然,也可以在命令行中以"-db"選項將其禁用;(建議設置項)
- uid/user:以指定的UID或用戶名身份運行haproxy進程;
- gid/group:以指定的GID或組名運行haproxy,建議使用專用於運行haproxy的GID,以免因許可權問題帶來風險;
- log:定義全局的syslog伺服器,接收haproxy啟動和停止的日誌。最多可以定義兩個;
log <address> <facility> [max level [min level]]
- log-send-hostname [string]:在日誌的最前面記錄本機主機名或string。遠程發送到日誌伺服器時可由此知道是haproxy主機發送的。
- pidfile:等同於命令行的"-p"選項。使用服務啟動腳本啟動haproxy時建議不要設置該項,以保證腳本能正確獲取pid文件。
- nbproc :指定啟動的haproxy進程個數,只能用於守護進程模式的haproxy;預設只啟動一個進程,一般只在單進程僅能打開少數文件描述符的場景中才使用多進程模式;(官方強烈建議不要設置該選項)
- ulimit-n:設定每進程能夠打開的最大文件描述符數量,預設haproxy會自動進行計算,因此不推薦修改此選項;(不建議設置項)
- stats:和多進程haproxy有關,由於不建議使用多進程,所以也不建議設置此項。但建議設置為"stats socket"將套接字和本地文件進行綁定,如"stats socket /var/lib/haproxy/stats"。
- node:定義當前節點的名稱,用於HA場景中多haproxy進程使用相同IP地址時分辨哪個node正處於使用狀態;
2.性能調整相關的參數。
- maxconn :設定每haproxy進程所接受的最大併發連接數,當達到此限定連接數後將不再接受新的連接。該參數特指和客戶端的連接數,不包括和服務端的連接。等同於命令行選項"-n";"ulimit -n"就是根據此值進行自動調整的;
- maxpipes :haproxy在使用splice()在內核中零複製時,是使用pipe傳遞進行報文粘接重組的,此選項用於設定每進程所允許使用的最大pipe個數;每個pipe會打開兩個文件描述符,因此"ulimit -n"自動計算時會按需調大此值;預設值為maxconn/4。調小時會影響一定的性能;
- noepoll:在Linux系統上禁用epoll機制;(不建議設置此項)
- nokqueue:在BSD系統上禁用kqueue機制;
- nopoll:禁用poll機制;
- nosplice:禁止在Linux套接字上使用內核tcp重組,這會導致更多的recv/send系統調用;(在內核版本2.6.28之後極度不建議設置此項)
- spread-checks <0..50, in percent>:在haproxy後端有著眾多伺服器的場景中,在精確的時間間隔後統一對眾伺服器進行健康狀況檢查可能會帶來意外問題;此選項用於將其檢查的時間間隔長度上增加或減小一定的隨機時長;預設為0,官方建議設置為2到5之間。(建議設置項)
- tune.bufsize :設定buffer的大小,同樣的記憶體條件下,較小的值可以讓haproxy有能力接受更多的併發連接,較大的值可以讓某些應用程式使用較大的cookie信息;預設為16384,可在編譯時修改,不過強烈建議使用預設值;(不建議設置項)
- tune.chksize :設定檢查緩衝區的大小,單位為位元組;更大的值有助於在較大的頁面中完成基於字元串或正則pattern的文本查找,但也會占用更多的系統資源;(不建議設置項)
- tune.maxaccept :設定haproxy進程內核調度運行時一次性可以接受的連接的個數,較大的值可以帶來較大的吞吐率,預設在單進程模式下為100,多進程模式下為8,設定為-1可以禁止此限制;(不建議設置項)
- tune.maxpollevents :設定一次io復用時系統調用可以處理的事件最大數,預設值取決於OS;其值小於200時可節約帶寬,但會略微增大網路延遲,而大於200時會降低延遲,但會稍稍增加網路帶寬的占用量;(不建議設置項)
- tune.maxrewrite :設定為首部重寫或追加而預留的緩衝空間,建議使用1024左右的大小;在需要使用更大的空間時,haproxy會自動增加其值;(不建議設置項)
- tune.rcvbuf.client :設定兩端的recv_buff大小(haproxy和客戶端建立tcp,和後端伺服器建立tcp,共兩端,因此有兩個recv_buff和兩個send_buff)。單位為位元組;(強烈推薦使用預設值)
- tune.rcvbuf.server :(強烈推薦使用預設值)
- tune.sndbuf.client:設定兩端的send_buff大小(強烈推薦使用預設值)
- tune.sndbuf.server:(強烈推薦使用預設值)
因此,拋去不建議設置的項後,global段的設置大致如下:這也是yum安裝haproxy時預設提供的配置
global
daemon
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
stats socket /var/lib/haproxy/stats
註意上面配置了使用local2記錄log,因此還需去rsyslogd的配置文件中添加該設備以及記錄的日誌位置。如下:
cat <<eof>>/etc/rsyslog.conf
local2.* /var/log/haproxy.log
eof
1.4 proxy配置段和常用配置選項
proxy配置部分是haproxy最重要的配置部分,包含下麵四種配置段:
- defaults []:設置frontend/backend/listen配置段的預設值。
- frontend :配置監聽客戶端連接的套接字。
- backend :配置haproxy所代理的後端伺服器組。
- listen :定義一個完整的前端和後端代理,但後端可以不定義。所以有時候等價於frontend+backend。它常用於綁定前後端1對1的情況。
所有代理的名稱只能使用大寫字母、小寫字母、數字、-(中線)、_(下劃線)、.(點號)和:(冒號)。此外,ACL名稱會區分字母大小寫。
目前,有兩種主流的代理模式:tcp代理(即所謂的4層代理)和http代理(即所謂的7層代理)。在4層代理模式下,haproxy簡單的在兩端進行雙向轉發。在7層代理模式下,haproxy會對協議進行分析,可以根據協議來允許、阻塞、切換、增加、修改和移除request或response中的屬性內容。
1.4.1 http事務模型相關設置
- (no) option http-keep-alive
啟用或禁用客戶端和服務端到haproxy之間的長連接。haproxy將處理所有請求和響應報文,請求完後haproxy兩端的連接都處於空閑狀態。 - (no) option http-server-close
啟用或禁用在haproxy處理完第一次響應之後關閉haproxy到服務端之間長連接的功能,但客戶端的長連接還保持,後續的每次請求都重新建立和後端的連接,每次響應後都關閉和後端的連接。啟用該選項時,haproxy將會在轉發給後端server的request數據包中添加一個"Connection:Close"標記,後端Server看到此標記就會在響應後關閉tcp連接。 - (no) option http-tunnel
啟用或禁用在haproxy處理完第一次請求和響應後關閉haproxy兩端長連接的功能。在1.0-1.5.21版本該項是預設項,但現在不建議使用,因為會產生一些問題。 - (no) option forceclose
啟用或禁用傳輸完響應報文後關閉兩端的連接。 - (no) option htthttpcloseose(廢棄選項)
- (no) option http-pretend-keepalive
有些伺服器會無視帶有"Connection:Close"標記的請求,從而http-server-close的後端發送響應後不會關閉tcp連接。設置該選項時,haproxy在收到響應後會主動關閉和後端的連接。不建議設置該選項,因為絕大多數伺服器都能正常工作並且有很好的調整能力。
一般來說,後端是靜態內容緩存伺服器時,或者就是靜態伺服器時,首選使用http-keep-alive模式,後端是動態應用程式伺服器時,首選使用http-server-close模式。
預設情況下,如果客戶端請求根據調度演算法被調度到另一臺後端伺服器時,http-keep-alive模式下和後端伺服器的空閑連接會立即斷開,並重新和被調度選中的後端伺服器建立連接。可以使用"prefer-last-server"選項,使得haproxy先查看當前保持的空閑連接是否可用,如果可用,則繼續使用該空閑連接,但是這樣會影響調度性能。
frontend和backend都可以設置這些模式選項,如果它們交叉設置了,最終何種模式會生效?例如,frontend設置了http-keep-alive,而bakcend設置了http-server-close時,取何種模式?計算方式採用如下矩陣:keepalive優先順序是最弱的,forceclose是優先順序是最高的。
1.4.2 balance
balance <algorithm>
可用於default、listen、backend配置段。
指定代理時負載均衡演算法,支持的演算法有:
- roundrobin(預設):根據權重進行輪詢,在伺服器的處理時間保持均勻分佈時,這是最平衡、最公平的演算法。此演算法是動態的,表示權重可以在haproxy運行時調整後端伺服器的權重並生效;
- static-rr:基於權重進行輪詢,與roundrobin類似,但是為靜態方法,在haproxy運行時調整其伺服器權重不會生效;
- leastconn:新的連接請求被派發至具有最少連接數目的後端伺服器;在有著較長時間會話的場景中推薦使用此演算法,如LDAP、SQL等,其並不太適用於較短會話的應用層協議,如HTTP;此演算法是動態的,可以在運行時調整其權重;
- source:將請求的源地址進行hash運算,使得同一個客戶端IP的請求始終被派發至某特定的伺服器;但當伺服器權重總數發生變化時,如某伺服器宕機或添加了新的伺服器,許多客戶端的請求可能會被派發至與此前請求不同的伺服器;類似於nginx的ip_hash,可用於負載均衡無cookie功能的基於TCP的協議。預設為靜態;
- uri:對URI的左半部分("?"標記之前的部分)進行hash運算,並除以伺服器的總權重來計算派發至某匹配伺服器;這可以使得對同一個URI的請求總是被派發至某特定的伺服器,除非伺服器的權重總數發生了變化;此演算法常用於代理緩存以提高緩存的命中率;但此演算法僅應用於提供http服務的後端伺服器;預設為靜態演算法;缺點是後端server宕機會造成嚴重抖動,可以通過hash-type設置hash演算法為一致性哈希解決。
- url_param:一般用於將同一用戶ID轉發至同一伺服器的情況。在使用了basic認證時,url中的param一般都會使用user=XXX。使用該演算法會對該參數進行hash運算,然後除以總權重以決定分配到哪台後端server。
- hdr(name):基於指定的請求首部名稱進行調度。首部中指定名稱相同的調度至同一伺服器。一般使用"hdr(host)"根據請求首部中的host即目標主機來進行hash運算。使用use_domain_only選項可以基於功能變數名稱來哈希,使得訪問www.longshuai.com和web.longshuai.com的請求都調度至同一伺服器。
- rdp-cookie
- rdp-cookie(name)
roundrobin和static-rr是有區別的,roundrobin是動態慢輪詢,不用重啟服務即可調整其權重,而static-rr必須重啟服務修改的權重才生效。例如原有2台後端server,新添加一臺後,roundrobin會從此時開始慢慢的將請求輪詢至此新伺服器,而static-rr由於需要重啟,所以重啟前新server不會被調度到,重啟後新server和舊server平均調度。一般來說,考慮加權輪詢的時候,roundrobin要比static-rr好。
一般可納入考慮的演算法有roundrobin/static-rr/leastconn/uri,其中leastconn演算法用於代理ldap、mysql等長時間會話連接的情況,uri演算法用於代理後端為緩存伺服器的情況。
(1). 用於調度MySQL伺服器,使用何種演算法?答:leastconn
(2). 用於調度靜態伺服器組,使用何種演算法?答:roundrobin
(3). 調度動態應用程式伺服器組,使用何種演算法?答:使用source。可以使用cookie指令來替代該演算法,因為cookie生效的優先順序高於調度演算法。
(4). 調度緩存伺服器,使用何種演算法?答:uri,且設置hash-type為一致性哈希演算法。
1.4.3 hash-type
hash-type <method>
不能用於frontend區段
定義用於將hash碼映射至後端伺服器的方法;可用方法有map-based和consistent,一般情況推薦使用預設的map-based方法。
- map-based:hash表是一個包含了所有線上伺服器的靜態數組。其hash值將會非常平滑,會將權重考慮在列,但其為靜態方法,對線上伺服器的權重進行調整將不會生效,這意味著其不支持慢速啟動。此外,挑選伺服器是根據其在數組中的位置進行的,因此,當一臺伺服器宕機或添加了一臺新的伺服器時,大多數連接將會被重新派發至一個與此前不同的伺服器上。對於緩存伺服器的工作場景來說,此方法不適用。
- consistent:(一致性哈希演算法)hash表是一個由各伺服器填充而成的樹狀結構;基於hash鍵在hash樹中查找相應的伺服器時,最近的伺服器將被選中。此方法是動態的,支持在運行時修改伺服器權重,因此相容慢速啟動的特性。添加一個新的伺服器時,僅會對一小部分請求產生影響,因此,適用於後端伺服器為cache的場景。不過,此演算法不甚平滑,派發至各伺服器的請求未必能達到理想的均衡效果,因此,可能需要不時的調整伺服器的權重以獲得更好的均衡性。
1.4.4 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),代理伺服器將通過指定的埠來接收客戶端請求;註意,小於1024的埠需要有特定許可權的用戶才能使用;<interface>
:指定物理介面的名稱;
例如:
bind :80,:443
bind 10.0.0.1:10080,10.0.0.1:10443
1.4.5 mode
指定haproxy實例運行模式。可為tcp、http。tcp為4層代理模式,不會對協議進行任何分析,只是單純地轉發數據包,如HTTPS/MYSQL等,http為7層代理模式。如果所有配置區段都沒有設置mode,則預設為tcp模式。
1.4.6 log
log global
log <address> <facility> [<level> [<minlevel>]]
為每個實例啟用事件和流量日誌,因此可用於所有區段。每個實例最多可以指定兩個log參數。配置方法和意義同前文全局配置參數的log。
如果使用log global,則表示從全局繼承日誌設置。另外,如果全局已經定義過兩個log了,此處除引用global外還自定義了一個log,則此自定義的log失效,因為只支持兩個日誌設置。
1.4.7 capture request header和capture response header
capture request header <name> len <length>
capture response header <name> len <length>
僅能用於"frontend"和"listen"區段
捕獲並記錄最近一次出現的指定請求首部或響應首部。請求首部是從客戶端發起的請求首部,響應首部是從後端server響應併在haproxy準備發送給客戶端前捕獲的。捕獲的首部值使用大括弧{}
括起來後會添加進日誌中。如果需要捕獲多個首部值,它們將以指定的秩序出現在日誌文件中,並以豎線"|"作為分隔符。不存在的首部記錄為空字元串。
最常需要捕獲的請求首部包括:在虛擬主機環境中使用的"Host"、上傳請求首部中的"Content-length"、快速區別真實用戶和網路機器人的"User-agent",以及代理環境中記錄請求真實來源的"X-Forward-For"。
一般需要捕獲的響應首部為:記錄還有多少內容需要接收的"Content-length"、跟蹤重定向路徑的"Location"。
<name>
:要捕獲的首部的名稱,此名稱不區分字元大小寫,但建議與它們出現在首部中的格式相同,比如大寫首字母。需要註意的是,記錄在日誌中的是首部對應的值,而非首部名稱。<length>
:指定記錄首部值時所記錄的精確長度,超出的部分將會被忽略。
可以捕獲的請求首部的個數沒有限制,但每個捕獲最多只能記錄64個字元。為了保證同一個frontend中日誌格式的統一性,首部捕獲僅能在frontend中定義。
例如:
capture request header Host len 15
capture request header X-Forwarded-For len 15
capture request header Referer len 15
capture response header Content-length len 9
capture response header Location len 15
1.4.8 maxconn
maxconn <conns>
不能用於backend區段
設定一個前端的最大併發連接數。對於大型站點來說,可以儘可能提高此值以便讓haproxy管理連接隊列,從而避免無法應答用戶請求。當然,此最大值不能超出"global"段中的定義。此外,haproxy會為每個連接維持兩個緩衝,每個緩衝的大小為8KB,再加上其它的數據,每個連接將大約占用17KB的RAM空間。這意味著經過適當優化後,有著1GB的可用RAM空間時將能維護40000-50000併發連接。
如果為指定了一個過大值,極端場景下,其最終占據的空間可能會超出當前主機的可用記憶體,這可能會帶來意想不到的結果;因此,將其設定了一個可接受值方為明智決定。預設為2000。
1.4.9 use_backend
use_backend <backend> [{if | unless} <condition>]
定義當滿足或不滿足什麼條件時使用哪個backend。條件判斷是可選的,並且condition是基於acl的條件。
1.4.10 default_backend
default_backend <backend>
不可應用於backend區段。
在沒有匹配的"use_backend"規則時為實例指定預設後端。在"frontend"和"backend"之間進行內容交換時,通常使用"use-backend"定義匹配規則;而沒有被規則匹配到的請求將由此參數指定的後端接收。
例如,已有兩組backend,名稱分別為dynamic和static,當不匹配use_backend時將預設使用dynamic作為轉發後端。
use_backend dynamic if url_dyn
use_backend static if url_css url_img extension_img
default_backend dynamic
1.4.11 server和default-server
server <name> <address>[:port] [param*]
聲明後端server,因此不能用於defaults和frontend區段。
default-server [param*]
指定server的預設參數值,不能用於frontend區段
-<name>
:為此伺服器指定的內部名稱,將出現在日誌及警告信息中;
<address>
:此伺服器的IPv4地址,也支持使用可解析的主機名;[:port]
:haproxy將請求轉發至後端伺服器的哪個埠,為可選項;未設定時,將使用客戶端請求時的同一埠;[param*]
:為此伺服器設定的一系列參數;可用的參數非常多,下麵是幾個常用的參數;
伺服器或預設伺服器參數:
backup
:設定為備用伺服器,當其它所有後端server均不可用時將啟用此server;disabled
:禁用此後端伺服器。check
:啟動對此server執行健康狀態檢查,但需要配合定義在backend的具體檢查方法(如httpcheck,mysql-check)才會進行指定的檢查方式,不指定檢查方法時將預設以tcp方式檢查。check可以藉助於額外的參數完成更精細的設定,如:inter <delay>
:設定健康狀態檢查的時間間隔,單位為毫秒,預設為2000;rise <count>
:設定server從離線狀態重新上線需要成功檢查的次數;不指定預設為2,一般可設置為1。fall <count>
:確認server從正常狀態轉換為不可用狀態需要檢查的次數;預設為3。
cookie <value>
:為指定server設定cookie值,指定的值將在請求入站時被檢查,第一次為此值挑選的server將在後續的請求中被選中,其目的在於實現基於客戶端cookie的持久連接;maxconn <maxconn>
:指定此後端伺服器接受的最大併發連接數(不同於全局設置的maxconn,全局的maxconn是面向客戶端的);如果發往此伺服器的連接數高於指定的值,將被放於請求隊列以等待其它連接釋放;maxqueue <maxqueue>
:設定請求隊列的最大長度;observe <mode>
:通過觀察伺服器的通信狀況來判定其健康狀態,預設禁用,支持的類型有"layer4"和"layer7",layer4表示檢查tcp連接是否正常,layer7僅用於http代理場景,通過後端server發送的response來判斷,例如可以判斷狀態碼,響應報文頭部是否無法解析等;redir <prefix>
:啟用重定向功能,將發往此伺服器的GET和HEAD請求均以302狀態碼響應,意味著不會將請求轉發至後端伺服器;在prefix後面不能使用/,且不能使用相對地址;例如:server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
weight <weight>
:權重,預設為1,最大值為256,0表示不參與負載均衡,即認為下線了不進行調度;
關於maxconn和maxqueue,這兩個值都是此後端伺服器的值。它們的大小和全局定義的maxconn是有一定大小比較關係的。如果沒有定義maxqueue,則全局maxconn應該小於或等於後端所有伺服器的maxconn之和,如果定義了maxqueue,則需要小於或等於後端所有伺服器的maxconn和maxqueue之和。否則haproxy接收進來的請求超過後端伺服器的壓力極限,可能壓垮後端。
例如:
server first 10.1.1.1:1080 cookie first check inter 1000
server second 10.1.1.2:1080 cookie second check inter 1000
server backup "${SRV_BACKUP}:1080" backup
server www1_dc1 "${LAN_DC1}.101:80"
server www1_dc2 "${LAN_DC2}.101:80"
default-server inter 1000 weight 13
1.4.12 option httpchk
option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>
不能用於frontend段。
此指令表示基於http協議來做健康狀況檢查,只有返回狀態碼為2xx或3xx的才認為是健康的,其餘所有狀態碼都認為不健康。不設置該選項時,預設採用tcp做健康檢查,只要能建立tcp就表示健康。
uri
:檢查的uri路徑,預設為"/"。接受帶有查詢參數的urimethod
:http檢查時使用的METHOD。不指定時預設為"OPTIONS"方法,也建議採用此方法,因為該請求方法對伺服器造成的資源損耗最小。version
:檢查的http協議版本,預設為http/1.0,但現在很多都採用HTTP/1.1,因此此處檢查版本需要修改為HTTP/1.1,但對於該版本的HTTP協議來說,還強制要求指定Host,中間使用\r\n
隔離。
例如下麵的配置,會將健康檢查時的頁面請求發送至後端192.168.1.1的80埠來確定該後端是正常的,但客戶端的請求將轉發至該後端的443埠。
backend https_relay
mode tcp
option httpchk
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
server apache1 192.168.1.1:443 check port 80
1.4.13 stats相關
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
stats hide-version
:啟用統計報告並隱藏HAProxy版本報告,不能用於"frontend"區段。stats realm
:stats auth身份認證時的提示信息。設置的提示信息中,如果有空白字元,則需要轉義。僅在與"stats auth"配合使用時有意義。stats auth
:啟用帶認證的統計報告功能並授權一個用戶帳號和對應的密碼(明文)。也就是說,想要查看統計報告需要提供身份和密碼。不能用於"frontend"區段。stats admin
:滿足指定條件時啟用統計報告頁面的管理功能,它允許通過web介面啟用或禁用後端伺服器。stats admin { if | unless } <cond>
下麵是兩個案例,第一個限制了僅能在本機打開報告頁面時啟用管理功能,第二個定義了僅允許通過認證的用戶使用管理功能。
backend stats_localhost
stats enable
stats admin if LOCALHOST
backend stats_auth
stats enable
stats auth haproxyadmin:password
stats admin if TRUE
1.4.14 option forwardfor
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
允許在發往伺服器的請求首部中插入"X-Forwarded-For"首部。
except <network>
:可選參數,當指定時表示請求中的源地址能匹配此網路時禁用此功能。header <name>
:可選參數,自定義首部名,如"X-Client"來替代"X-Forwarded-For"。有些獨特的web伺服器的確需要一個獨特的首部。if-none
:僅在此首部不存在時才將其添加至請求報文問道中。
HAProxy工作於反向代理模式,其發往伺服器的請求中的客戶端IP均為HAProxy主機的地址而非真正客戶端的地址,這會使得伺服器端的日誌信息記錄不了真正的請求來源,"X-Forwarded-For"首部則可用於解決此問題。HAProxy可以向每個發往伺服器的請求上添加此首部,並以客戶端IP為其value。
下麵是一個例子。
frontend www
mode http
option forwardfor except 127.0.0.1
1.4.15 錯誤頁面相關
- errorfile
在用戶請求不存在的頁面時,返回一個頁面文件給客戶端而非由haproxy生成的錯誤代碼;可用於所有段中。errorfile <code> <file>
<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
- errorloc和errorloc302
請求錯誤時,返回一個HTTP重定向至某URL的信息;可用於所有配置段中。errorloc <code> <url> errorloc302 <code> <url>
<code>
:指定對HTTP的哪些狀態碼返回指定的頁面;這裡可用的狀態碼有200、400、403、408、500、502、503和504;<url>
:Location首部中指定的頁面位置的具體路徑,可以是在當前伺服器上的頁面的相對路徑,也可以使用絕對路徑;需另外,這兩個關鍵字都會返回302狀態嗎,這將使得客戶端使用同樣的HTTP方法獲取指定的URL,對於非GET方法的場景(如POST)來說會產生問題,因為返回客戶端的URL是不允許使用GET以外的其它方法的。如果的確有這種問題,可以使用errorloc303來返回303狀態碼給客戶端。
- errorloc303
請求錯誤時,返回一個HTTP重定向至某URL的信息給客戶端;可用於所有配置段中。errorloc303 <code> <url>
<code>
:指定對HTTP的哪些狀態碼返回指定的頁面;這裡可用的狀態碼有400、403、408、500、502、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
1.4.16 cookie和option redispatch
在backend伺服器組啟用cookie功能,以便實現cookie綁定。需要同時設置server指令中的cookie選項。
後端為靜態伺服器設置:
cookie NAME insert nocache
PHP做後端時設置:
cookie SESSION_COOKIE insert indirect nocache
當客戶端綁定cookie對應的後端伺服器宕機後,應該為此客戶端重新調度一個後端server,否則將打不開頁面。這時需要使用option redispatch,表示當找不到cookie對應的伺服器時分配新的伺服器給客戶端。
1.4.17 reqadd和rspadd
reqadd <string> [{if | unless} <cond>]
rspadd <string> [{if | unless} <cond>]
滿足條件時向請求首部或響應首部的尾端添加自定義的欄位。條件可選,當不給定條件時表示所有的請求首部或響應首部尾端都添加欄位。
其中string包含了欄位名和欄位值,當然,既然是自定義,值肯定是可以省略的。註意,空白字元需要轉義。
例如:
acl is-ssl dst_port 443
reqadd X-Proto:\ SSL if is-ssl
1.4.18 超時時間相關
時間單位預設都是毫秒。
- timeout http-request
haproxy等待客戶端請求發送完整的超時時長。如果一開始發送了一部分,後續沒有再發送,或者後續發送的一直是請求的某一部分,等達到超時時間將斷開此連接。這可以防止DoS攻擊。 - timeout queue
當調度的後端伺服器已經滿負載了,即達到了該backend的最大併發連接數時,後續要調度到此backend的請求將進入隊列等待後端伺服器釋放可用。該超時時間設置的就是某一請求在隊列中的最大等待時長,當達到此時長後將被認為該請求永遠無法到達服務端,haproxy會丟棄該請求並向客戶端返回503狀態碼。 - timeout connect 和retries
haproxy要和後端伺服器建立連接時等待超時時間。一般如果haproxy和後端伺服器處於區域網中,建立連接是瞬間的,所以該值可以設置的小一些。
retries表示和服務端建立連接失敗時重試連接的次數。 - timeout client
客戶端和haproxy之間非活動連接保持的最大時長,達到此時長haproxy將斷開和此客戶端的連接。非活動表示客戶端沒有請求報文發送給haproxy。 - timeout server
服務端和haproxy之間非活動連接保持的最大時長,達到此時長haproxy將斷開和此伺服器的連接。非活動表示服務端沒有響應報文發送給haproxy。 - timeout http-keep-alive
等待出現http請求報文出現的最大時長,即和客戶端保持長連接的時長。建議設置小一些,以儘快釋放連接,例如設置為2-3秒鐘。
如果此項未設置,則使用timeout http-request值,如果timeout http-request也沒設置,則使用timeout client的值。 - timeout check
在和服務端建立連接後,健康狀況檢查判斷的超時時長。
1.4.19 http協議過濾:http-request
http-request {allow | auth [realm <realm>] | redirect <rule> | deny [deny_status <status>]} [{if | unless} <condition>]
做7層http協議過濾。當http協議相關項滿足條件時執行一個action,可以執行的action非常多,此處只列出了幾項。
allow
:表示接受該http請求。auth
:表示提示輸入用戶認證信息,指定realm時將給出提示信息。redirect
:重定向功能。deny
:表示拒絕該http請求。
acl nagios src 192.168.129.3
acl local_net src 192.168.0.0/16
acl auth_ok http_auth(L1)
http-request allo