代理相關配置參數
內容參考自馬哥教育
HAProxy官方文檔 https://cbonte.github.io/haproxy-dconv/2.0/configuration.html
URI Syntax:
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag> //<scheme>表示協議;<user>:<password>可以省略;<params>表示參數;?<query>表示查詢字符串;
URI的左半部分是:<scheme>://<user>:<password>@<host>:<port>/<path>;<params>
;<params>
ftp://downloads.dongshi.com/pub/gnu;type=d //type=d就是指明了類型,是一個params
http://www.dongshi.com/hammers;sale=false/index.html;graphics=true //紅色部分為params
?<query>
http://www.joes-hardware.com/inventory-check.cgi?item=12741 //?item=12741表示要把item=12741當作查詢條件,通過URL(紅色部分)把條件發送給服務器端,然后服務器端會把查詢條件嵌入到php或jsp的頁面程序當中,由這個頁面程序基於mysql或者其他存儲協議發往服務器端,並由服務器端執行並取回結果,所以?item=12741是查詢字符串。
什么情況下可以用到URI算法?(調度方式:對URL做hash計算,將計算結果除以總權重數)
當后端服務器是緩存服務器時特別有用,即無論哪個客戶端發出請求,只要資源鏈接是同一個,haproxy主機都可以始終把請求發送至同一個backend server(緩存服務器)。假如有一個資源鏈接在之前沒有被用戶請求過,所以並沒有緩存,那么haproxy就會根據后端緩存服務器的權重挑選一個backend server響應用戶的請求。一旦根據算法挑選backend server結束,haproxy內部就會維護一個hash表,表中存儲的是鍵值對,鍵是URL的hash值,值是之前挑選出的對應的backend server的地址,因此如果有客戶端再次請求同一個資源鏈接時,haproxy會把URL做hash計算,對比內部維護的hash表,有相同的鍵就直接把這個請求發送到鍵對應的值的backend server中。
URI算法示例(根據請求的URL進行調度)
# vim /etc/haproxy/haproxy.cfg //在代理服務器上進行操作
1 #--------------------------------------------------------------------- 2 # static backend for serving up images, stylesheets and such 3 #--------------------------------------------------------------------- 4 backend websrvs 5 balance uri //使用uri算法 6 hash-type consistent //類型為consistent 7 server web1 192.168.128.132:80 check 8 server web2 192.168.128.133:80 check
# systemctl reload haproxy
# systemctl status haproxy
# for i in {1..10}; do echo "<h1>Page $i on node2" > /var/www/html/test$i.html; done //在node2上添加10個頁面
# for i in {1..10}; do echo "<h1>Page $i on node3" > /var/www/html/test$i.html; done //在node3上添加10個頁面
從上面的圖片可以看出,利用uri算法可以把同一個資源鏈接始終發送至后端的同一個backend server,無論使用什么樣的請求方式。如果其中一台backend server宕機的話,haproxy會把這個主機上的請求發送至另外一台haproxy主機。
hdr算法演示:根據用戶的User-Agent進行調度
# vim /etc/haproxy/haproxy.cfg //修改內容如下
1 backend websrvs 2 balance hdr(User-Agent) 3 hash-type consistent 4 server web1 192.168.128.132:80 check 5 server web2 192.168.128.133:80 check
# systemctl reload haproxy
# for i in {1..5}; do echo "<h1>Page$i on node2</h1>" > /var/www/html/ceshi$i.html; done //在node2上創建web頁面
# for i in {1..5}; do echo "<h1>Page$i on node3</h1>" > /var/www/html/ceshi$i.html; done //在node3上創建web頁面
可以看出不同的User-Agent請求相同的資源鏈接會被調度至不同的服務器
代理參數:
balance: 指明調度算法;
動態:權重可動態調整
靜態:調整權重不會實時生效
roundrobin: 輪詢(加權輪詢),動態算法,每個后端主機最多支持4128個連接;
static-rr: 輪詢,靜態算法,每個后端主機支持的數量無上限;
leastconn: 根據后端主機的負載數量進行調度;僅適用長連接的會話;動態;
source:這種算法有靜態和動態兩種,取決於hash類型
hash-type:
map-based:取模法;靜態;
consistent:一致性哈希法;動態;
uri:
hash-type
map-based:更省資源
consistent:由於服務器總會上下線,所以一般會把hash-type設置為consistent
url_param: 根據url中的指定的參數的值進行調度;把值做hash計算,並除以總權重;比如sale=false/index.html的值就是false/index.html。功用:在url中添加一個參數,根據用戶請求參數值的類型來做出調度決策。
hash-type
map-based:
consistent:
hdr(<name>):根據請求報文中指定的header(如use_agent, referer, cookie,hostname)進行調度;把指定的header的值做hash計算;
hash-type
map-based:
consistent:
bind:做綁定,指明要監聽的地址
bind [<address>]:<port_range> [,...]
bind [<address>]:<port_range> [,...] interface <interface>
示例:
# vim /etc/haproxy/haproxy.cfg
1 #--------------------------------------------------------------------- 2 # main frontend which proxys to the backends 3 #--------------------------------------------------------------------- 4 frontend main 5 bind *:80 //修改如下 6 bind *:8080 //注意如果端口進行改動,一定要重啟服務,reload是不起作用的 7 default_backend websrvs 8 9 10 #--------------------------------------------------------------------- 11 # static backend for serving up images, stylesheets and such 12 #--------------------------------------------------------------------- 13 backend websrvs 14 balance hdr(User-Agent) 15 hash-type consistent 16 server web1 192.168.128.132:80 check
# systemctl restart haproxy
# ss -tunl //可以看到已經監聽了8080端口
tcp LISTEN 0 128 *:8080 *:*
tcp LISTEN 0 128 *:80 *:*
bind只能用於frontend, listen(listen既能面向前端,又能面向后端):
因為作為代理服務器,當客戶端的請求過來時,代理服務器haproxy需要接受用戶的請求,所以需要監聽端口;
而當代理服務器把客戶端的請求重構后並把自己扮演為客戶端的向后端的backend server請求時,代理服務器接受backend server的響應報文是不需要監聽端口的。
mode:指明haproxy實例運行時的模式或協議
HAProxy的工作模式有兩種:http協議的 反向代理、tcp鏈接協議的負載均衡;默認為tcp;
tcp, http, health
log:
maxconn:設定前端最大並發連接數
后端有多個backend sevrer,對於最大連接數的設置有以下幾個:在前端可以定義多個frontend或者多個listen,每一個frontend都要通過backend把用戶的請求發往后端的backend server,而maxconn是定義每一個前端的最大連接數。如果是定義在全局上就是整個服務器的最大連接數,在global中也可以定義maxconn,所有的frontend或者listen的最大連接數加起來等於全局的。如果把最大連接數定義在frontend或者listen中則是設置前端的,前端的請求會通過某一個后端負載均衡至后端的服務器,一個backend可以定義多個后端主機。為了避免后端主機被壓垮,可以在backend中設置后端服務器可以承載的鏈接數,應該設定所有后端服務器可承受的連接數量應該大於等於前端的最大並發連接數的。
default_backend:定義默認后端
為frontend指明使用的默認后端;
use_backend: 條件式后端調用;
K.I.S.S: Keep it simple, stupid.
server:
server <name> <addr>[:port] [param*]
[param*]有很多選項
backup: 設定當前server為backup server;
check: 健康狀態檢測,有三種:(注意:健康狀態檢測信息不應該記錄在日志中,因為這些信息會非常占用空間)
inter <delay>:檢測時間間隔;單位為ms, 默認為2000;
fall: up --> down, soft state, soft state, hard state;
rise:down --> up,
cookie <value>:每一個用戶請求通過前端到達backend,backend會根據算法挑出一個后端服務器。后端服務器把響應報文由haproxy響應給客戶端時,同時backend 會把backend指向后端服務器的cookie信息也發給客戶端一份,比如backend把客戶端的信息調度到node1,那么cookie信息就會指明是node1。如 果是基於cookie信息綁定的話,當同一個客戶端再來請求時,haproxy就會檢查請求所帶的cookie信息,因此就會知道此前挑選了node1,就會發往 同一個服務器。這個cookie是會話級別的,而不是基於源地址綁定。客戶端經過haproxy代理服務器請求時,代理服務器會重構報文因此報文的源地址 都是代理服務器的地址即源地址是一樣,但請求報文中攜帶者客戶端的cookie信息,所以代理服務器會基於cookie信息把請求發往不同的后端服務器。
maxconn: 此服務接受的並發連接的最大數量;
maxqueue: 請求隊列的最大長度;
observe: 根據流量判斷后端server的健康狀態;
weight: 指定權重,默認為1,最大為256;0表示不被調度;
redir <prefix>: 重定向;所有發往此服務器的請求均以302響應;
server srv1 192.168.128.132:80 redir http://imageserver.nihaocom check //指調度時所有發往192.168.128.132:80主機的請求都重定向至http://imageserver.nihaocom主機,prefix指http://imageserver.nihaocom后面不能跟"/"。后端real server重定向。
后端http服務時的健康狀態的檢測方法:(只能是http協議)
option httpchk
基於瀏覽器cookie實現session sticky:
cookie <name>:name是必須的,是cookie自己的名字,跟給server發送的信息是沒有關系的。當一個用戶發出請求,haproxy會操作客戶端發送請求所攜帶的cookie信息,雖然客戶端攜帶的cookie信息已經有了之前訪問所對應的backend server的信息,但是haproxy會在原有的基礎之上加上其他標識信息,這個另加信息只為haproxy使用,那么如何使用?在backend中為每一個后端real server指明一個唯一的cookie標識,把這個表示插入客戶端每一次訪問的cookie信息中去。把這個標識插入到原有cookie中什么位置?有三種方式:1、把原有cookie重寫,拋棄之前的cookie;2、insert,即把標識插入到cookie中去;3、prefix,把標識附加在原有cookie的前面。但是insert方式最為常見。
啟用基於cookie的每客戶端會話綁定示例演示
要點:
(1) 每個server有自己惟一的cookie標識(websrv1/websrv1);
(2) 在backend中定義為用戶請求調度完成后操縱其cookie。
# vim /etc/haproxy/haproxy.cfg
1 #--------------------------------------------------------------------- 2 # main frontend which proxys to the backends 3 #--------------------------------------------------------------------- 4 frontend main 5 bind *:80 6 bind *:8080 7 default_backend websrvs 9 10 #--------------------------------------------------------------------- 11 # static backend for serving up images, stylesheets and such 12 #--------------------------------------------------------------------- 13 backend websrvs 14 balance roundrobin 15 cookie SERVERID insert nocache indirect //如果希望用戶請求發送至后端real server后能基於cookie會話綁定的話,就需要添加cookie參數的配置信息。
//在這里把cookie的name取為SERVERID,SERVERID的值會被賦予websrv1或者websrv2,這要取決於請求被調度上哪個real server上,insert是指明cookie的給定方式 16 server web1 192.168.128.132:80 check weight 1 cookie websrv1 //添加cookie信息,客戶端訪問時會在原有的cookie信息后面插入web1信息 17 server web2 192.168.128.133:80 check weight 3 cookie websrv2 //必須是唯一標識
# systemctl status haproxy
啟用stats:
listen statistics
bind *:9090
stats enable
stats hide-version
#stats scope .
stats uri /haproxyadmin?stats
stats realm "HAPorxy\ Statistics"
stats auth admin:mageedu
stats admin if TRUE
向日志中記錄額外信息:
capture request header
capture response header
當mode為http時,記錄豐富的日志信息:
option httplog
錯誤頁面重定向:
errorfile: 使用haproxy主機本地文件進行響應;
errorloc, errorloc302: 使用指定的url進行響應,響應狀態碼為302;不適用於GET以外的其它請求方法;
errorloc303:返回303狀態碼;
訪問控制:
http_request
tcp_request
添加請求或響應報文首部:
reqadd
rspadd
ACL
定義,及調用;