HAProxy是一個使用C語言編寫的,提供負載均衡,以及基於TCP(僞四層)和HTTP(七層)的應用程序代理。
HAProxy特別適用於那些負載大的web站點,這些站點一般又須要會話保持或七層處理。HAProxy徹底能夠支持數以萬計的併發鏈接。而且它的運行模式使得它能夠很簡單安全的整合進您當前的架構中, 同時能夠保護你的web服務器不被暴露到網絡上。
HAProxy實現了一種事件驅動, 單一進程模型,此模型支持很是大的併發鏈接數。多進程或多線程模型受內存限制 、系統調度器限制以及無處不在的鎖限制,不多能處理數千併發鏈接。事件驅動模型由於在有更好的資源和時間管理的用戶空間(User-Space) 實現全部這些任務,因此沒有這些問題。
前端
haproxy安裝不算很難,haprox官方base源已經被收錄,也可使用源碼編譯。mysql
安裝haproxylinux
yum install haproxy -y
1.安裝開發環境nginx
yum groupinstall "development tools" -y
2.下載源碼包web
wget https://src.fedoraproject.org/repo/pkgs/haproxy/haproxy-1.8.12.tar.gz/sha512/2b782a54988cc88d1af0e5f011af062910e8fac28eab13db7e05a58d0d23961f827da47e3871e8d081f5a2d222588480d81dec2e9f14ec9f54a1c3cb5bf3d56a/
3.解壓並安裝redis
tar -xvf haproxy-1.8.12.tar.gz cd haproxy-1.8.12 #獲取內核版本信息 uname -r # TARGET=linux310,內核版本,使用uname -r來查看 # ARCH指明系統的位數 # PREFIX指明安裝的路徑 make TARGET=linux310 ARCH=x86_64 PREFIX=/usr/local/haproxy make install PREFIX=/usr/local/haproxy
4.準備配置文件算法
#建立對應目錄 mkdir /usr/local/haproxy/conf #建立配置文件 cd /usr/local/haproxy/conf vim haproxy.cfg #這裏複製一份yum安裝的配置文件就好,也能夠本身寫一份
5.添加用戶sql
useradd -r -s /usr/sbin/nologin haproxy
# -f指明配置文件,配置文件必定要寫對,不然沒法啓動haproxy /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg
全局配置段(global):(建議不作改動,會自動調整)
1.進程與安全配置相關的參數設定;
2.性能參數配置段;
3.Debug參數配置段;
4.用戶列表段;
5.peer段
代理配置段(proxies):
1.defaults段:默認參數的配置段,在本段配置的參數值,默認會被自動引用到以後的frontend段,backend段和listen段,因此,若是某些參數屬於公用的配置段,那麼能夠在default段進行配置便可。若是在frontend段,backend段和listen段進行配置的參數同時在default也有相應參數配置的話,default段的配置會被覆蓋掉。
2.frontend段:本段負責配置接收用戶請求的虛擬前端節點。相似於nginx的server{}部分。
3.backend段:本段用於設置集羣后端服務器集羣的配置,也就是用來定義一組真實服務器,來處理用戶發出的請求。添加的真實服務器相似於LVS中的real-server,至關於nginx中的 upstream {}段
4.listen段:同時用來負責配置前端和happ後端。express
#經常使用配置項 log: 全局日誌文件配置條目,local2表示日誌設備,最多可定義兩個 nbproc:要啓動的haproxy的進程數量 chroot: chroot 切換根目錄,將haproxy都運行在/var/lib/haproxy 這樣作是爲了增長haproxy的安全。 pidfile:指定haproxy的進程pid文件,啓動進程的用戶必需要有訪問該文件的權限。 maxconn:設定每一個haproxy進程能夠接受的最大併發鏈接數。 user和group:指定運行haproxy的用戶和組 daemon: 設置haproxy之後臺運行的方式運行。 maxconnrate:每一個進程每秒最大處理的鏈接數量。 maxse***ate:每一個進程每秒能夠建立的最大會話速率。 maxsslconn:設定每一個haproxy進程所能接受的ssl最大併發鏈接數。
#經常使用配置項 mode:設置haproxy實例默認的運行模式,默認是http,支持tcp,http可選值 tcp模式:在該模式之下,客戶端會與服務器端創建一個全雙工鏈接,不對七層報文作檢查,經常使用語ssl,ssh,smtp等服務。 http模式:客戶端在請求轉發到後端服務器以前會被分析。 log global:繼承全局日誌 option dontlognull:保證HAProxy不記錄上級負載均衡發送過來的用於檢測狀態沒有數據的心跳包。 option http-server-close:客戶端與服務器端在完成一次鏈接請求以後,HAProxy會主動關閉該TCP鏈接,有助於提升性能。 xforwardfor:因爲haprxoy工做在反向代理方向,所以後端的真實服務器可能沒法獲取真實的請求端ip,使用xforwardfor能夠在報文中封裝新的字段記錄請求端ip,httpd的話要在默認日誌格式中進行修改才能夠記錄。 redispatch:是否容許在session 失敗後從新分配。 retries:設置鏈接後端服務器的失敗重試次數,鏈接失敗的次數若是超過這裏設置的值,haproxy將會將對應的後端服務器設置爲不可用狀態。 timeout connect: 成功鏈接到一臺服務器的最長等待時間,默認爲毫秒,能夠換用其餘單位。 timeout client:鏈接客戶端發送數據的最長等待時間,默認毫秒,可修改。 timeout server:服務器端迴應客戶端數據發送的最長等待時間,默認毫秒,能夠修改。 timeout check:設置對後端服務器的檢測超時時間,默認毫秒,能夠修改
bind :80,:443 同時監聽2個端口(之間不能有空格,監聽端口要重啓服務) bind ip:port,ip:port bind /var/****.sock 使用套接字文件
roundrobin:輪詢,依次訪問每個後端ip(短鏈接和無狀態的鏈接推薦使用rr算法) server options: weight # 支持配置權重 動態算法:支持權重的運行時調整,支持慢啓動;每一個後端中最多支持4095個server; static-rr:靜態算法:不支持權重的運行時調整及慢啓動;後端主機數量無上限;
配置文件:
請求效果
加權輪詢
效果
vim
leastconn:推薦使用在具備較長會話(長鏈接,有狀態)的場景中,例如MySQL、LDAP等; first:先到先得,根據服務器在列表中的位置,自上而下進行調度;前面服務器的鏈接數達到上限,新請求才會分配給下一臺服務; source:源地址hash,本質上是source ip,將同一個ip的請求發往同一服務器,用於保持會話。(snat模式與後端服務器宕機會出現問題) 除權取餘法(一旦服務器組發生變化會產生巨大影響):map-based 一致性哈希(最佳,可是因爲作大量運算會影響性能):consistent uri:對URI的左半部分作hash計算,並由服務器總權重相除之後派發至某挑出的服務器;有助於提高緩存命中率。 <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag> 左半部分:/<path>;<params> 整個uri:/<path>;<params>?<query>#<frag> username=jerry
uri 算法測試
效果
url_param:對用戶請求的uri的<params>部分中的參數的值做hash計算,並由服務器總權重相除之後派發至某挑出的服務器;一般用於追蹤用戶,以確保來自同一個用戶的請求始終發往同一個Backend Server; hdr(<name>):對於每一個http請求,此處由<name>指定的http首部將會被取出作hash計算; 並由服務器總權重相除之後派發至某挑出的服務器;沒有有效值的會被輪詢調度; hdr(Cookie) rdp-cookie rdp-cookie(<name>) hash-type:哈希算法 hash-type <method> <function> <modifier> map-based:除權取餘法,哈希數據結構是靜態的數組; consistent:一致性哈希,哈希數據結構是一個樹; <function> is the hash function to be used : 哈希函數 sdbm djb2 wt6
hdr算法匹配報文字段請求(這裏匹配的是瀏覽器)
效果
name:服務器在haproxy上的內部名稱,主要出如今日誌和警告中;
address:服務器地址,可使用主機名替代(重要)
maxconn <maxconn>:當前server的最大併發鏈接數;
backlog <backlog>:當前server的鏈接數達到上限後的後援隊列長度;
backup:設定當前server爲備用服務器;
check:對當前server作健康狀態檢測;默認是tcp的檢測,要關注狀態變化
addr :檢測時使用的IP地址; port :針對此端口進行檢測; inter <delay>:連續兩次檢測之間的時間間隔,默認爲2000ms; rise <count>:連續多少次檢測結果爲「成功」才標記服務器爲可用;默認爲2; fail <count>:連續多少次檢測結果爲「失敗」才標記服務器爲不可用;默認爲3; 注意:option httpchk,"smtpchk", "mysql-check", "pgsql-check" and "ssl-hello-chk" 用於定義應用層檢測方法;
cookie <value>:爲當前server指定其cookie值,用於實現基於cookie的會話黏性;
disabled:標記爲不可用;通常用來作發佈
on-error <mode>:後端服務故障時的行動策略;
- fastinter: force fastinter - fail-check: simulate a failed check, also forces fastinter (default) - sudden-death: simulate a pre-fatal failed health check, one more failed check will mark a server down, forces fastinter - mark-down: mark the server immediately down and force fastinter
redir <prefix>:將發往此server的全部GET和HEAD類的請求重定向至指定的URL;
weight <weight>:權重,默認爲1。
對後端服務器作http協議的健康狀態檢測:
option httpchk option httpchk <method> <uri> option httpchk <method> <uri> <version> 定義基於http協議的7層健康狀態檢測機制
配置狀態頁
啓用統計頁;基於默認的參數啓用stats page;
- stats uri : /haproxy?stats 訪問頁默認地址,支持重寫 - stats realm : "HAProxy Statistics" - stats auth : no authentication - stats scope : no restriction
示例
maxconn <conns>:爲指定的frontend定義其最大併發鏈接數;默認爲2000;
Fix the maximum number of concurrent connections on a frontend.
mode { tcp|http|health }:定義haproxy的工做模式;
tcp:基於layer4實現代理;可代理mysql, pgsql, ssh, ssl等協議;
http:僅當代理的協議爲http時使用;
health:工做爲健康狀態檢查的響應模式,當鏈接請求到達時迴應「OK」後即斷開鏈接;
例子:
listen ssh bind :22011 balance leastconn mode tcp server sshsrv1 192.168.99.131:22 check server sshsrv2 192.168.99.135:22 check
forwardfor [ except <network> ] [ header <name> ] [ if-none ]
在由haproxy發日後端主機的請求報文中添加「X-Forwarded-For」首部,其值前端客戶端的地址;用於向後端主發送真實的客戶端IP;
[ except <network> ]:請求報請來自此處指定的網絡時不予添加此首部;
[ header <name> ]:使用自定義的首部名稱,而非「X-Forwarded-For」
示例:
haproxy配置文件
後端httpd配置文件(修改後要重啓httpd服務)
測試效果:記錄了原地址。
rspadd <string> [{if | unless} <cond>]在http響應首部添加字段信息
rspadd X-Via:\ douma
reqdel <search> [{if | unless} <cond>]在http響應包首都中刪除匹配到的信息
rspidel(i忽略字符大小寫) Server.*
示例:能夠用來實現刪除server信息,以防暴露站點漏洞
修改前
haproxy配置文件
新效果:
acl <aclname> <criterion> [flags] [operator] [<value>] ...
aclname:設定acl的名稱
value:設定acl的值
boolean:布爾型 integer or integer range:整數或者範圍 ip address /network:ip地址或者網絡地址 string :字符串 exact:精確匹配 substring:子串匹配 suffix:前綴匹配 prefix:後綴匹配 subdir:子路徑匹配 domain:子域匹配 regular expression:正則表示模式匹配 hex block:十六進匹配
flag標誌位
<flags> -i : 在子串匹配時候忽略大小寫 -m : 使用特定匹配模式(不多使用) -n : 忽略dns作名稱解析 -u : 要求ACL使用惟一名稱 -- : force end of flags. Useful when a string looks like one of the flags.
[operator] 匹配整數值:eq、ge、gt、le、lt 匹配字符串: - exact match (-m str) : the extracted string must exactly match the patterns ; - substring match (-m sub) : the patterns are looked up inside the extracted string, and the ACL matches if any of them is found inside ; - prefix match (-m beg) : the patterns are compared with the beginning of the extracted string, and the ACL matches if any of them matches. - suffix match (-m end) : the patterns are compared with the end of the extracted string, and the ACL matches if any of them matches. - subdir match (-m dir) : the patterns are looked up inside the extracted string, delimited with slashes ("/"), and the ACL matches if any of them matches. - domain match (-m dom) : the patterns are looked up inside the extracted string, delimited with dots ("."), and the ACL matches if any of them matches. acl做爲條件時的邏輯關係: - AND (implicit) - OR (explicit with the "or" keyword or the "||" operator) - Negation with the exclamation mark ("!") if invalid_src invalid_port 要求同時知足 if invalid_src || invalid_port 或表示 if ! invalid_src invalid_port 取反,不知足第一個可是知足第二個
<criterion> : dst : ip 目標ip或者範圍 dst_port : integer 目標端口或範圍 src : ip 源ip或者範圍 src_port : integer 源端口後綴範圍 acl invalid_src src 172.16.200.2 path : string 七層檢查 /path;<params> path : exact string match 精確匹配 path_beg : prefix match 前綴匹配 path_dir : subdir match 子串匹配 path_dom : domain match 子域匹配 path_end : suffix match 路徑後綴匹配 path_len : length match 長度匹配 path_reg : regex match 正則匹配 path_sub : substring match 子串匹配
示例
path_beg /images/ 除去ip:port以後以/images/開頭 path_end .jpg .jpeg .png .gif url以jpg jpeg png gif後綴的文件 path_reg ^/images.*\.jpeg$ images開頭 jpeg結尾 path_sub image path_dir jpegs path_dom ilinux /images/jpegs/20180312/logo.jpg
url : string 對url進行匹配 url : exact string match url_beg : prefix match url_dir : subdir match url_dom : domain match url_end : suffix match url_len : length match url_reg : regex match url_sub : substring match
req.hdr([<name>[,<occ>]]) : string hdr([<name>[,<occ>]]) : exact string match hdr_beg([<name>[,<occ>]]) : prefix match hdr_dir([<name>[,<occ>]]) : subdir match hdr_dom([<name>[,<occ>]]) : domain match hdr_end([<name>[,<occ>]]) : suffix match hdr_len([<name>[,<occ>]]) : length match hdr_reg([<name>[,<occ>]]) : regex match hdr_sub([<name>[,<occ>]]) : substring match