HAproxy基礎服務實現及相關參數講解

HAproxy簡單概述

HAProxy是免費極速且可靠的用於爲TCP和基於HTTP應用程序提供代理服務的解決方案。是工做在應用空間的程序,跟Nginx同樣受限於套接字。且只類同於Nginx四層和七層代理服務器僅此而已。但更多用在web反向代理上!!! 
HAProxy還能夠將後端的服務器與網絡隔離,起到保護後端服務器的做用。HAProxy的負載均衡能力雖不如LVS,但也是至關不錯。並且因爲其工做在7層,能夠對http請求報文作深刻分析,按照本身的須要將報文轉發至後端不一樣的服務器(例如動靜分離),這一點工做在4層的LVS沒法完成。 
其中一點點不一樣Nginx的是一個Master Worker模型負責接收用戶請求,裝載配置文件,平滑升級…可是更多的用戶請求是經過worker來實現。而HAProxy是單一進程模型,支持多進程,但更多建議使用單一進程模型。使用單個進程直接響應用戶多個請求,不啓用子進程。也可以支持單進程巨大併發鏈接數,且必須支持事件驅動,若是不支持事件驅動,併發效率是可想而知。javascript

HAproxy工做模式

HAProxy的工做模式通常有兩種 
tcp模式:實例運行於TCP模式,在客戶端和服務器端之間將創建一個全雙工的鏈接,且不會對7層報文作任何類型的檢查,只能以簡單模式工做。此爲默認模式,一般用於SSL、SSH、SMTP等應用。 
http模式:實例運行於HTTP模式,客戶端請求在轉發至後端服務器以前將被深度分析,全部不與RFC格式兼容的請求都會被拒絕。 
注意:當實現內容交換時,前端和後端必須工做於同一種模式(通常都是HTTP模式),不然將沒法啓動實例。 
工做模式可經過mode參數在default,frontend,listen,backend中實現定義。 
兩種模塊分別是:經過mod_tcp來限定反代模式和mod_http來實現負載均衡 
幫助文檔地址:http://cbonte.github.io/haproxy-dconv/,其它的地址就別想了css

HAproxy演示環境

實驗平臺:Windows10_64 
虛擬環境:基於Win系統搭建的VMware虛擬主機實現 
所須要的虛擬主機:三臺,CentOS 7.2或者是CentOS 6.8,偏移CentOS 7.2 
虛擬主機各IP:node1–10.1.15.40, node2–10.1.15.41 node3–10.1.15.42 
node1節點–10.1.15.40,安裝haproxy,其它兩個節點作後端輪詢。 
base收錄版本1.5,可是立刻要廢棄了。官方最新版是1.7開發板(演示1.5)html

HAproxy的安裝

haproxy已經收錄到了base倉庫,因此咱們直接yum安裝就能夠了,由於我這裏實驗使用的Centos7系統,因此仍是使用YUM,其它發行版本可另行抉擇。 
若是遇到yum安裝報錯You could try using –skip-broken to work around the problem 
可移除yum.repos.d目錄下的全部文件,只留base.repo文件而後yum clean all 
再執行yum install前端

[root@localhost yum.repos.d]# yum install haproxy -y

HAproxy程序環境:

配置文件:/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:先後端的直接組合;

簡單實現用haproxy實現後端主機代理,簡單均衡 
一、> vim /etc/haproxy.cfg 在haprxoy 10.1.15.40主機上修改如下內容 
frontend main 
bind *:80,*:8080 
default_backend web 
# static backend for serving up p_w_picpaths, stylesheets and such 
backend web 
balance roundrobin 
server web1 10.1.15.41:80 check 
server web2 10.1.15.42:80 check 
二、在後端兩臺主機安裝httpd啓動服務,給指定網頁分別叫backend1和backend2 
10.1.15.41 
vim /var/www/html 
<h1> backend 1 <h1> 
10.1.15.42 
vim /var/www/html 
<h1> backend 2 <h1> 
java

HAproxy相關配置參數全局段:

global配置參數: 
進程及安全配置相關的參數:user/uid, group/gid, nbproc, ulimit-n, ca-base, … 
log < address > [len < length >] < facility > [ max level [min level]] 
定義日誌相關配置屬性address是日誌服務器的地址, [len < length >]是每行日誌記錄的最大長度 
舉例:如何記錄haproxy的日誌呢? 
一、 讓haproxy服務器啓用接收遠程主機所傳來的日誌信息 
二、 若是啓用local2.,指明local2.日誌記錄於何處 
三、若是啓用日誌,使用udp和tcp均可以,咱們這裏使用的udp,把註釋去掉node

vim /etc/rsyslog.conf 第一步
#Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514

指明日誌記錄到哪裏去  第二步
#Save boot messages also to boot.log
local2.*   /var/log/haproxy.log
systemctl restart rsyslog.service,確保UDP 514端口被監聽
[root@localhost log]# cat haproxy.log 
Nov 12 13:26:24 localhost haproxy[23610]: 10.1.15.85:6703 [12/Nov/2016:13:26:24.829] main web/web1 0/0/0/3/3 200 280 - - ---- 1/1/0/1/0 0/0 "GET / HTTP/1.1"

性能調優相關參數 
maxconn < number>:設定單haproxy進程的最大併發鏈接數; 
maxconnrate < number>:設定單haproxy進程每秒所能接受的鏈接數; 
maxsslconn < number>:設定單haproxy進程的ssl鏈接最大併發鏈接數; 
maxsslrate < number>:單haproxy進程的ssl鏈接的建立速率上限; 
spread-checks <0..50, in percent> 
向後端主機作健康狀態檢測時,該如何散開檢測機制 
tune.bufsize < number> 緩衝池大小 
tune.rcvbuf.client < number> 接收客戶端請求時緩衝池大小 
tune.rcvbuf.server < number> 接收後端服務器的響應時緩衝池大小 
tune.sndbuf.client < number> 向客戶端發送響應 
tune.sndbuf.server < number> 向服務端發送請求 
tune.ssl.cachesize < number> ssl的緩存大小 
tune.ssl.lifetime < timeout> ssl的緩存會話的有效時長 
Debugging: 
debug 儘可能輸出詳細信息 
quiet 不輸出詳細信息 
Userlists:定義用戶、組及用戶列表; 
userlist < listname > 
group < groupname > [users < user >,< user >,(…)] 
user < username > [password|insecure-password < password >] 
strong text[groups < group >,< group >,(…)] 
Peers:把多個haproxy定義構建爲同步集羣 
peer 
peers 
其它未盡詳細的參數請參考官方幫助文檔 
http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#3.1mysql

HAproxy相關配置參數代理段:

關於代理段的詳細參數在這裏就很少說,仍是請參考官方文檔,太多了看起來頭疼 
簡要說下HAproxy的工做模式」Mode」 
Mode能夠工做在default,listen.backend和frontend中,用來定義HAproxy到底工做在應用層仍是傳輸層 
Mode主要用來定義haproxy的三種工做模型: 
tcp:基於layer4實現代理,可代理大多數基於tcp的應用層協議,例如ssh/mysql/pgsql等; 
http:工做在應用層,客戶端的http請求會被深度解析; 
health:工做爲健康狀態檢查響應模式,當請求到達時僅迴應「OK」即斷開鏈接;nginx

HAproxy調度算法:

定義負載均衡的算法除了listen和backend段中也能夠放在defaults段中,定義格式: 
balance < algorithm > [ < arguments > ] 
balance url_param [check_post [< max_wait >]] 
常見的調度算法 
roundrobin: 
動態算法:支持權重的運行時調整,支持慢啓動;僅支持最大4095個後端活動主機 
server後面使用weight來定義權重; 
static-rr: 
基於權重進行輪詢與roundrobin相似靜態算法:不支持權重的運行時調整及慢啓動;但後端主機數量無限制; 
leastconn: 
新的鏈接請求被派發至具備最少鏈接數目的後端服務器,動態算法,適用於較長時間會話的場景。 
source: 
將請求的源地址進行hash運算,並與後端服務器的總權重做取模運算後調度至某臺服務器;同一IP地址的請求將始終被調度至某特定的服務器,可使用hash-type修改此特性來肯定動態仍是靜態算法 
hash表如何創建映射:除權重取模法,一致性hash 
hash-type: 
map-based:取模法,hash數據結構是靜態數組; 
consistent:一致性哈希,哈希的數據結構是「樹」; 
uri: 
對URI的左半部分(「?」以前的部分)或整個URI進行hash運算,並與後端服務器的總權重做取模運算後調度至某臺服務器;同一URI的請求將始終被調度至某特定的服務器,靜態算法,可使用hash-type修改此特性;git

hdr(< name >): 
根據用戶請求報文中指定的http首部的值進行調度,經常使用於實現對同一個虛擬主機的請求始終發往同個backend server。 
first: 
先到先得,服務器名稱標識字符最短的優先調用。一臺用完才用第二臺,忽略權重。github

**演示示例**

更改調度算法爲source,把同一IP地址的請求將始終被調度至某特定的服務器
vim /etc/haproxy/haproxy.cfg
backend web
    balance     roundrobin //修改成source
    server       web1 10.1.15.41:80 check
    server       web2 10.1.15.42:80 check
systemctl reload haproxy.service //測試:http://19.1.15.40 

更改調度算法爲uri,把同一頁面請求經過調度算法發往到後端指定服務器
vim /etc/haproxy/haproxy.cfg
backend web
    balance     roundrobin //修改成uri
    server       web1 10.1.15.41:80 check
    server       web2 10.1.15.42:80 check
for i in {1..10}; do echo "test page $i at BACKEND 1 " > /var/www/html/test$i.html; done
systemctl reload haproxy.service

測試:
for i in {1..10}; do curl http://10.1.15.40/test$i.html;done
結果:把同一個被請求到的頁面始終發往到指定的後端服務器上

更改調度算法爲hdr,把同一瀏覽器的請求,始終發往到後端指定服務器上
vim /etc/haproxy/haproxy.cfg
backend web
    balance     roundrobin //修改成hdr(User-Agent)
    server       web1 10.1.15.41:80 check
    server       web2 10.1.15.42:80 check
systemctl reload haproxy.service
測試:
for i in {1..10}; do curl http://10.1.15.40/test$i.html;done 
結果:只要瀏覽器同樣,請求始終被調度到指定後端服務器上

調整服務器的最大併發鏈接數,並啓用stats頁面作認證

定義併發數有兩種方法: 
一種,全局定義,一種默認定義 
vim /etc/haproxy/haproxy.cfg 
frontend main //在此下面定義maxconn 10000 
bind * :80, * :8080 
maxconn 10000 
定義stats頁面,在代理配置段四項中均可以定義 
vim /etc/haproxy/haproxy.cfg 
frontend main 
bind :80,:8080 
maxconn 10000 //最大併發鏈接數 
stats enable // 開啓stats頁面 
stats uri /admin?stats //自定義stats頁面 
default_backend web //默認的後端主機標識web 
stats realm stats\ page\ area //開啓認證界面 
stats auth admin:admin //認證用戶名密碼 
stats hide-version //隱藏版本信息 
stats refresh 5s //指定stats頁面5秒刷新一次 
stats admin if TRUE //內建訪問控制列表 
測試:http://10.1.15.40/haproxy?stats

對後端服務器作健康情況檢測

check爲server的參數,可啓動對此server執行健康狀態的檢測。check藉助其額外的參數可實現更精細的監測機制。 
inter < delay>: 
健康狀態檢測的時間間隔,單位爲毫秒,默認爲2000,可使用fastinter和downinter來根據服務器端狀態優化此時間延遲 
rise < count>: 
健康狀態檢測中某離線的server從離線狀態轉換至正常狀態須要成功檢查的次數 
fall < count>: 
確認server從正常狀態轉換爲不可用狀態須要檢查的次數 
默認爲傳輸層檢測,即探測端口是否能響應。 
須要執行應用層檢測,則須要 
httpchk, smtpchk, mysql-check, pgsql-check, ssl-hello-chk; 
vim /etc/haproxy/haproxy.cfg 
backend web //下面修改內容 
balance roundrobin 
server web1 10.1.15.41:80 weight 2 maxconn 5000 check inter 1 rise 1 fall 2 
server web2 10.1.15.42:80 weight 1 maxconn 3000 check inter 1 rise 1 fall 2 
測試:10.1.15.40/haproxy?stats

對後端服務器作加權輪詢

vim /etc/haproxy/haproxy.cfg
backend web //在後端主機下列加入
balance roundrobin
server  web1 10.1.15.41:80 check weight 2 maxconn 5000 cookie web1
server  web2 10.1.15.42:80 check weight 1 maxconn 3000 cookie web2
systemctl reload haproxy.service

測試:
for i in {1..10}; do curl http://10.1.15.40/index.html;done 
結果:權重weight,併發maxconn,指定的值cookie 
注意:修改後端服務器的調度算法:必定要重啓haproxy的服務,reload是不成功

基於cookie的session綁定

在響應報文中添加cookie信息,下一次的客戶請求會帶上這個cookie信息,服務器端根據cookie將請求始終定向至後端的某一臺服務器,可用於保持session會話。 
而cookie信息該怎麼插入進來 
rewrite: 從新改寫原有的全部cookie 
insert: 在原有cookie信息當中插入 
prefix: 在原有cookie附加爲前綴

舉例:把基於瀏覽器的用戶會話訪問,對當前服務器講第一次調度到某個主機,那麼就調度某主機
vim /etc/haproxy/haproxy.cfg
backend web //在後端主機下列加入
balance roundrobin
cookie webserver insert nocache indirect
server  web1 10.1.15.41:80 check weight 2 maxconn 5000 cookie web1
server  web2 10.1.15.42:80 check weight 1 maxconn 3000 cookie web2
服務器第一次爲某客戶度挑選中的主機,會把webserver中的參數值賦值到web1上或者web2上
systemctl reload haproxy.service

測試:
for i in {1..10}; do curl http://10.1.15.40;done 
[root@localhost haproxy]# curl -I 10.1.15.40

自定義haproxy錯誤頁面

vim /etc/haproxy/haproxy.cfg
frontend  main 
bind *:80,*:8080
maxconn 10000
stats enable
default_backend web
stats realm stats\ page\ area
stats auth admin:admin
stats hide-version
stats refresh 5s
stats admin if TRUE
#errorfile 503 /etc/haproxy/errorfiles/503sorry.http //直接以文件形式顯示錯誤頁面
errorloc 503 http://10.1.15.40:9527/errorpagetest.html // 直接以url形式顯示錯誤頁面,重定向302
errorloc 503 http://www.baidu.com
mkdir /etc/haproxy/errorfiles      
vim  /etc/haproxy/errorfiles/503sorry/http
< h1 >sorry page home < h1 >
systemctl reload haproxy.service

測試:stop後端全部主機,而後請求haproxy前端主機地址 :10.1.15.40option forwardfor

客戶端的請求經前端的代理服務器轉發至後端的web服務器,代理服務器在轉發時將目標地址改成後端的某臺web服務器地址,將源地址由client ip(客戶端地址)改成本身面向後端服務器的地址。後端的web服務器若使用默認格式記錄日誌,則記錄的客戶端IP地址都爲前端的代理服務器地址。這時須要在發日後端的請求報文中添加內容爲客戶端IP地址的首部,以便後端的web服務器可以正確獲取客戶端地址。 
x-forwardfor 
在配置文件默認段裏已經定義了轉發,因此咱們直接用就能夠了。 
vim /etc/haproxy/haproxy.cfg 
defaults 
option forwardfor except 127.0.0.0/8 
而後修改兩臺後端主機的httpd.conf文件,vim /etc/httpd/conf/httpd.conf 
把LogFormat %h修改成{X-forwarded-For}i 
重啓服務systemctl restart httpd.service 
在haproxy前端主機上刷新下頁面。而後在後端主機看日誌是否記錄的是客戶端的真實地址就能夠。 
tail /var/log/httpd/access.log看請求的是真實的客戶端地址功能就實現了。

修改請求或響應報文首部相關:

增長響應報文相關信息 
frontend main 
rspadd X-Via:\ HAProxy/1,5 
rspidel Server.* 
rspadd X-Via:\ HAProxy/1,5 
客戶端請求看一看在Response Headers報文裏有沒有值:X-Via:HAProxy/1,5 
刪除響應報文Server相關信息 
rspidel Server.*

ACL basics

HAPAroxy的ACL可以經過檢測請求報文的首部、響應報文的內容或其餘的環境狀態信息做出轉發決策,加強了其配置彈性。 
配置分兩步驟:首先定義ACL,即定義一個測試條件,再定義動做,即知足測試條件的狀況下執行的某特定動做。 
語法格式: 
acl < aclname> < criterion> [flags] [operator] [< value>] … 
取值類型: 
– boolean 
– integer or integer range 
– IP address / network 
– string (exact, substring, suffix, prefix, subdir, domain) 
– regular expression 
– hex block 
匹配的操做符:數值匹配,字符串匹配,邏輯條件等… 
注意注意:語法太多,讓人很蛋疼,簡直太頭疼,咋麼那麼多 
注意注意:自定義ACL所有都是小寫

四層匹配,舉例:
vim /etc/haproxy/haproxy.cfg
在 frontend  main 中定義
acl myhost src 10.1.15.85
acl myport dst_port 8080
block if !myhost myport
任何人試圖去訪問8080端口時,但不是來自於myhost主機就所有拒絕 
七層匹配,舉例:
acl text_file  path_end  -i  .txt
block if text_file
任何人去試圖訪問txt文件,結尾不區分大小寫的所有拒絕
舉例:匹配某個瀏覽器類型
acl chrome hdr_reg(User-Agent) -i .*chrome.*$
block if chrome

HTTP層訪問控制指令

acl valid_method method GET HEAD
http-request deny if ! valid_method 
舉例:
acl myhost src 10.1.15.40
http-request deny if url_admin !myhost

動靜分離

frontend main *:5000 
acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheets 
acl url_static path_end -i .jpg .gif .png .css .js 
use_backend static if url_static //若是上面的條件知足調至backend static主機 
default_backend app //不然調至app主機 
backend static 
balance roundrobin 
server static 127.0.0.1:4331 check 
round robin balancing between the various backends 
backend app 
balance roundrobin 
server app1 127.0.0.1:5001 check 
server app2 127.0.0.1:5002 check 
server app3 127.0.0.1:5003 check 
server app4 127.0.0.1:5004 check 

done!!!

相關文章
相關標籤/搜索