1. 程式人生 > >HAProxy入門及常用配置模擬測試

HAProxy入門及常用配置模擬測試

調整 yum 邏輯 下載 src 布爾型 狀態 計算 star

HAProxy簡介

??
??HAProxy是一個使用C語言編寫的,提供負載均衡,以及基於TCP(偽四層)和HTTP(七層)的應用程序代理。
??HAProxy特別適用於那些負載大的web站點,這些站點通常又需要會話保持或七層處理。HAProxy完全可以支持數以萬計的並發連接。並且它的運行模式使得它可以很簡單安全的整合進您當前的架構中, 同時可以保護你的web服務器不被暴露到網絡上。
??HAProxy實現了一種事件驅動, 單一進程模型,此模型支持非常大的並發連接數。多進程或多線程模型受內存限制 、系統調度器限制以及無處不在的鎖限制,很少能處理數千並發連接。事件驅動模型因為在有更好的資源和時間管理的用戶空間(User-Space) 實現所有這些任務,所以沒有這些問題。

??

HAProxy與LVS對比

??

1.都是負載均衡的實現產品,但是LVS是基於Linux操作系統的軟負載均衡;HAProxy是基於第三方應用的軟負載均衡。

??

2.LVS是基於四層的IP負載均衡方案;HAProxy是同時具有四層和七層的,可以提供TCP和HTTP應用的負載均衡方案。

??

3.LVS工作在OSI參考模型的四層,所以其狀態監控功能比較簡陋,HAProxy在狀態監控方面更為優秀,可以支持基於端口,URL,腳本等多種狀態監測方法。

??

4. HAProxy在整體性能上明顯低於四層負載的LVS;LVS技術由於Linux系統內核的支持有著接近於硬件設備的負載能力。

??

部署及配置文件介紹

安裝部署

haproxy安裝不算很難,haprox官方base源已經被收錄,也可以使用源碼編譯。

yum安裝

安裝haproxy

    yum install haproxy -y

源碼編譯安裝

1.安裝開發環境

    yum groupinstall "development tools" -y

2.下載源碼包

wget https://src.fedoraproject.org/repo/pkgs/haproxy/haproxy-1.8.12.tar.gz/sha512/2b782a54988cc88d1af0e5f011af062910e8fac28eab13db7e05a58d0d23961f827da47e3871e8d081f5a2d222588480d81dec2e9f14ec9f54a1c3cb5bf3d56a/

3.解壓並安裝

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.添加用戶

useradd -r -s /usr/sbin/nologin haproxy
  1. 啟動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後端。

配置文件詳解

global配置段

技術分享圖片

#常用配置項
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最大並發連接數。

default配置段

技術分享圖片

#常用配置項
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:設置對後端服務器的檢測超時時間,默認毫秒,可以修改

重點配置參數

1.bind:配置監聽套接字,不能有默認值,不能用在backend中。
bind :80,:443 同時監聽2個端口(之間不能有空格,監聽端口要重啟服務)
bind ip:port,ip:port
bind /var/****.sock 使用套接字文件
2.balance:後端服務器組內的調度算法
roundrobin:輪詢,依次訪問每一個後端ip(短連接和無狀態的連接推薦使用rr算法)
    server options: weight #  支持配置權重
    動態算法:支持權重的運行時調整,支持慢啟動;每個後端中最多支持4095個server;
    static-rr:靜態算法:不支持權重的運行時調整及慢啟動;後端主機數量無上限;

配置文件:
技術分享圖片
請求效果
技術分享圖片
加權輪詢
技術分享圖片
效果
技術分享圖片

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算法匹配報文字段請求(這裏匹配的是瀏覽器)
技術分享圖片
效果
技術分享圖片

3.default_backend:設置默認的後端主機組,在frontend中定義
4.server的配置,定義後端主機的各個服務器及選項。同一後端主機可以被多個backend引用。

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。

5.基於cookie做會話綁定

技術分享圖片
技術分享圖片

6.httpchk健康狀態檢測

對後端服務器做http協議的健康狀態檢測:

                    option httpchk
                    option httpchk <method> <uri>
                    option httpchk <method> <uri> <version>     
                    定義基於http協議的7層健康狀態檢測機制
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訪問控制

指令結構

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 

HAProxy入門及常用配置模擬測試