1、HAProxy簡介
HAProxy 是一款高效能TCP/HTTP 反向 Proxy負載平衡伺服器,具有如下功能:
根據靜態分配的cookies完成HTTP請求轉寄
在多個伺服器間實現負載平衡,並且根據HTTP cookies 實現會話粘性
主備伺服器切換
接受訪問特定連接埠實現服務監控
實現平滑關閉服務,不中斷已建立串連的請求響應,拒絕新的請求
在請求或響應HTTP報文中添加,修改,或刪除首部資訊
根據正則規則阻斷請求
提供帶有使用者認證機制的服務狀態報表頁面
HAProxy特別適用於那些負載特大的web網站,這些網站通常又需要會話保持或七層處理。HAProxy運行在時下的硬體上,完全可以支援數以萬計的 並發串連。並且它的運行模式使得它可以很簡單安全的整合進您當前的架構中, 同時可以保護你的web伺服器不被暴露到網路上。
HAProxy 實現了一種事件驅動、單一進程模型,此模型支援非常大的並發串連數。多進程或多執行緒模式受記憶體限制 、系統調度器限制以及無處不在的鎖限制,很少能處理數千並發串連。事件驅動模型因為在有更好的資源和時間管理的使用者端(User-Space) 實現所有這些任務,所以沒有這些問題。此模型的弊端是,在多核系統上,這些程式通常擴充性較差。這就是為什麼他們必須進行最佳化以 使每個CPU時間片(Cycle)做更多的工作。
HAProxy實際工作中,它佔用使用者空間時間要比核心已耗用時間少20倍,所以對系統參數調優是十分必要的一項工作。
另外衡量一個負載平衡伺服器主要考量三個指標
session rate
此項指標非常重要,它決定了一個load balancer 能不能分發所有接受的請求。這項指標通常是由CPU效能決定。測量指標的大小跟傳輸的每個對象的大小有關,通常用Null 物件來測試,Session rates 在 100,000 sessions/s 左右,使用 Xeon E5 在 2014測試。
session concurrency
該指標與前一指標相關聯。這一指標與伺服器記憶體和系統可以處理的檔案描述符數量有關。 通常每個session佔用34KB,即大概3W個session佔用1GB記憶體空間,實際上,socket buffer也會佔用記憶體空間,2W個session socket佔用1GB記憶體。
data forwarding rate
這一指標與 session rate 相對立,它的衡量單位通常是 Megabytes/s (MB/s), 或者 Gigabits/s (Gbps)。傳輸較大的對象有利於該指標的提升,因為較大的對象傳輸可以減少session建立和關閉浪費的時間。而測量session rate 則在傳輸小對象時有利於指標提升。haproxy 在2014年使用 Xeon E5 測試成績為40 Gbps。
2、HAProxy程式環境
本文環境:CentOS7.2 haproxy 1.5 通過yum 安裝
程式環境: 設定檔:/etc/haproxy/haproxy.cfg Unit File: haproxy.service 主程式:/usr/sbin/haproxy 設定檔: global:全域配置段 進程及安全配置相關的參數 效能調整相關的參數 Debug相關的參數 proxies:代理配置段 defaults:為frontend, backend以及listen提供預設配置; frontend:前端,相當於Nginx中的server{ ... }; backend:後端,相當於nginx中的upstream { ... }; listen:前後端的直接組合; **關於前端與後端的關係:一個前端可以指向多個後端;同時一個後端可以被多個調用。
3、HAProxy配置詳解
3.1 global配置段
3.1.1 進程相關配置
定義日誌系統相關屬性
log <address> [len <length>] <facility> [max level [min level]]
harpoxy 將日誌發送到指定的rsyslog伺服器,在本地記錄也要開啟rsyslog服務;
全域端最多可配置兩個log 伺服器;
< address> :Log Service器地址
[ len ] 指定記錄的日誌最大長度
定義運行使用者,所屬組
username
group groupname
運行方式
意味著後台守護進程 3.1.2 參數調優
maxconn <number>:設定單haproxy進程的最大並發串連數; maxconnrate <number>:設定單haproxy進程每秒接受的串連數; maxsslconn <number>:設定單haproxy進程的ssl串連最大並發串連數; maxsslrate <number>:單haproxy進程的ssl串連的建立速率上限; spread-checks <0..50, in percent>:避免對於後端檢測同時並發造成 的問題,設定錯開時間比,範圍0到50,一般設定2-5較好。
3.1.3 使用者列表
用於對haproxy 狀態監控頁面的使用者認證。至少要定義一個使用者列表並且添加一個使用者
密碼可以加密或明文。
Example:
userlist L1 group G1 users tiger,scott group G2 users xdb,scott user tiger password $6$k6y3o.eP$JlKqe4(...)xHSwRv6J.C0/D7cV91 user scott insecure-password elgato user xdb insecure-password hellouserlist L2 group G1 group G2 user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1 user scott insecure-password elgato groups G1,G2 user xdb insecure-password hello groups G2
3.2 proxy配置段
這部分配置在下列定義地區下使用
- defaults < name > - frontend < name > - backend < name > - listen < name >
“defaults” 地區定義了frontend,backend,listen 的預設參數
“frontend“ 地區描述了接收用戶端請求的監聽配置
”backend“ 地區描述接受請求處理的後端伺服器配置
”listen“ 地區描述一組前端和後端直接一對一綁定的組配置
HAProxy 配置的關鍵字與地區限制特性,即有些關鍵字在某個地區不可以使用
下面開始講解關鍵字的用法 3.2.1 常用配置指令
1. bind [<address>]:<port_range> [, ...] [param*]
僅在frontend和listen地區使用。定義服務監聽連接埠地址等參數
[ param* ] 參數根據系統而定,一般不需要指定
example:
bind :80 #監聽本機所有IP的80連接埠bind *:80 #監聽本機所有IP的80連接埠bind 192.168.12.1:8080,10.1.0.12:8090
2. mode {tcp|http|health}
tcp:基於layer4實現代理,可代理大多數基於tcp的應用程式層協議,例如ssh/mysql/pgsql等;
http:用戶端的http請求會被深度解析;
health:工作為健康狀態檢查響應模式,當請求到達時僅回應“OK”即中斷連線;
3. balance <algorithm> [ <arguments> ] balance url_param <param> [check_post]
在backend地區定義調度演算法
< algorithm > 如下:
roundrobin
帶有權重的輪詢調度演算法;server後面使用weight來定義權重;動態演算法:支援權重的運行時調整,支援慢啟動(緩慢接收大量請求在剛啟動時);僅支援最大4095個後端活動主機
static-rr
靜態roundrobin演算法;
不支援權重的運行時調整及慢啟動;但後端主機數量無限制;
leastconn
帶權重的最少串連分配動態演算法;
適用長串連應用協議,如ssh等
first
第一優先演算法;
如果第一個服務端可接受請求則總是把串連分配給它,直到第一個服務端處於繁忙,分配給下一個,順序按服務端的數字ID從小到大排列
source
源IP hash 演算法;
該演算法保證在後端伺服器組沒有減少或增加的情況下,能將來自同一用戶端IP的請求分配至同一個服務端;
該演算法適合在無法使用cookie插入的TCP模式下使用
動態演算法或靜態演算法取決於hash-type;
uri
uri hash 演算法;
該演算法hash uri 的查詢標記的左側部分,或者指定whole 參數時hash全部uri;
該演算法保證訪問同一uri的請求分配至同一服務端,適用於後端為快取服務器的情況,以提高快取命中率;
動態演算法或靜態演算法取決於hash-type;
另外:該演算法支援追加參數[ < arguments > ]:
(1) whole :hash完整uri
(2) len number:hash指定uri的長度
(3) depth nubmer:hash指定目錄深度,每個"/"代表一個深度
uri_param
param hash 演算法;
對使用者請求的url中的< param >部分中的指定的參數的值(uri中"="部分)作hash計算;
該演算法適用於有使用者識別參數的uri ,它保證同一user id 的請求分配至同一服務端;
若果check_post 標識啟用,則在uri中沒有找到"?"參數時,對HTTP Post 請求實體尋找參數聲明;
動態演算法或靜態演算法取決於hash-type;
Example:
balance url_param useridbalance url_param session_id check_post 64
hdr(< name >)
HTTP 首部欄位hash演算法;
指定的http首部將會被取出做hash計算。如果沒有值,則降至輪詢調度;
動態演算法或靜態演算法取決於hash-type;
4. hash_type < method >
在balance 指令中選定與hash 有關的演算法,都會受此影響。
預設採取的方法為map-based
< method > 如下:
map-based:模數法,hash資料結構是靜態數組;
該hash是靜態,不支援線上調整權重,不支援慢啟動;
該演算法調度平滑,後端伺服器能夠均勻承受負載;
缺點也是明顯的:當伺服器的總權重發生變化時,即有伺服器上線或下線,都會導致調度結果整體改變。如果想避免此種情況應採用consistent 方法;
consistent:一致性雜湊,雜湊的資料結構是“樹”;
該hash是動態,支援線上調整權重,支援慢啟動
每一個server 會在"樹"中出現多次, 在樹中尋找hash key,並選擇最近的server;
該方法的優點在於,當伺服器的總權重發生變化時,對調度結果影響是局部的,不會引起大的變動。所以十分適合快取服務器;
缺點:該演算法不夠平滑,很容易導致後端伺服器負載不均衡。所以很有必要對伺服器的權重以或者伺服器ID進行調整;
為保持均勻負載,應該保證所有伺服器ID保持一致;
5. server <name> <address>[:[port]] [param*] default-server [param*]
server用於在backend和listen中定義一個主機;
default-server 用於設定server的預設參數;
[param*] 如下:
weight < weight >:當前server的權重;
id < number > :設定server ID
cookie < value >:為當前server指定其cookie值,此值會在收到請求報文時進行檢測,其功能在於實現基於cookie會話保持;
check:對當前server進行健康狀態檢測;
inter < delay >:時間間隔;
rise < count >:判定為“健康”狀態需要檢測的次數,預設2;
fall < count >:判定為“不健康”狀態需要檢測的次數,預設3;
addr <ipv4|ipv6>:健康狀態檢測時使用的地址;
port < port >:健康狀態檢測時使用的連接埠;
注意:預設為傳輸層檢測,即探測連接埠是否能響應;需要執行應用程式層檢測,則需要httpchk, smtpchk, mysql-check, pgsql-check, ssl-hello-chk;
maxconn <maxconn>:當前server的最大並發串連數;
maxqueue <maxqueue>:當前server的等待隊列的最大長度;
disabled:將主機標記為不可用;
redir <prefix>:將發往當前server的所有請求GET和HEAD類的請求均重新導向至指定的URL;
Examples :server first 10.1.1.1:1080 id 3 cookie first check inter 1000 maxconn 10000 maxqueue 2000server second 10.1.1.2:1080 id 4 cookie second check inter 1000
6. option httpchk option httpchk <uri> option httpchk <method> <uri> option httpchk <method> <uri> <version>
基於http協議作7層健康狀態檢測機制,預設是基於tcp層進行檢測;
TCP 模式也可以使用該檢測機制
< method > < uri > < version >:請求報文的超始行;
method 預設方法為 OPTIONS;返回狀態代碼2XX,3XX意味成功;
Examples :# Relay HTTPS traffic to Apache instance and check service availability# using HTTP request "OPTIONS * HTTP/1.1" on port 80.backend https_relay mode tcp option httpchk OPTIONS /index.html HTTP/1.1\r\nHost:\ www server apache1 192.168.1.1:443 check port 80
7. http-check expect [!] <match> <pattern>
定義檢測有效期間望值;
! 表示認定的錯誤值;< match > 可取值為:
status < string >
rstatus < regex > 正則方式
string < string >
rstring < regex >
Examples :# only accept status 200 as validhttp-check expect status 200# consider SQL errors as errorshttp-check expect ! string SQL\ Error# consider status 5xx only as errorshttp-check expect ! rstatus ^5# check that we have a correct hexadecimal tag before /htmlhttp-check expect rstring <!--tag:[0-9a-f]*</html>
8. cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
啟用基於cookie的會話黏性,要結合server指定的cookie參數一起實現;
常用形式:cookie WEBSRV insert nocache indirect
Example:backend websrvsbalance roundrobincookie WEBSRV insert nocache indirectserver web1 10.1.0.68:80 check weight 2 maxconn 5000 cookie web1server web2 10.1.0.69:80 check weight 1 maxconn 3000 cookie web2
9. default_backend <backend>
當use_backend 的使用規則沒有被匹配時,由default_backend 指定預設伺服器組;
關於use_backend 使用後續會在acl 章節中講解; 3.2.2 log 相關
為frontend或backend定義日誌記錄機制;
log global :使用全域定義的日誌記錄方式log <address> [len <length>] <facility> [<level> [<minlevel>]]:自訂no log :不記錄capture request header <name> len <length>-->記錄請求報文中的指定的首部的值於日誌中;len用於指定要記錄的資訊的長度;capture response header <name> len <length>-->記錄響應報文中的指定的首部的值於日誌中;len用於指定要記錄的資訊的長度;樣本: capture request header Referer len 30
3.2.3 自訂錯誤頁面
- errorfile <code> <file>
< code > 指定HTTP返回的狀態代碼。200, 400, 403, 408, 500, 502, 503, and 504 可使用;
< file > 指定一個檔案代替HTTP響應;
Example:errorfile 503 /etc/haproxy/errorfiles/503sorry.http