Linux Haproxy
Haproxy是一款基於TCP(4層傳輸層)和HTTP應用(7層應用層)的代理軟件,它能夠做爲負載均衡器,由於是開源軟件,因此徹底免費;Haproxy默認使用的是事件驅動、單一進行模型,相似nginx,一個進程響應多個請求;它具備如下特性:
高可用性:Haproxy能夠在負載均衡服務出現故障時自動的將服務從故障節點切換到其事先配置好的備用節點,保證了服務的不間斷提供;
可擴展性:隨着業務量的加大,現有的集羣規模不能知足需求時,能夠向集羣中動態的添加後端服務器節點,知足業務的須要;
但是可控性:Haproxy提供了一個監控頁面,能夠對集羣服務或後端服務器節點進行實時的監控,能夠在出現故障時根據各類方式(郵件,短信等)通知管理員,及時進行故障排除;
安全性:Haproxy提供了對後端服務器進行健康狀態檢測的機制,能夠定時探測後端服務器的狀態,在後端服務器負載飽和前,能夠自動屏蔽新來的鏈接,以保證服務器的正常使用;
高性能:Haproxy藉助於OS上的幾種常見的技術來實現性能的最大化;
1.默認爲單進程、採用事件驅動模型,顯著下降了進程上下文切換的開銷以及內存的佔用;
2.採用O(1)事件檢查器,容許其在高併發鏈接中對任何鏈接的任何事件實現即時探測;O(1)能夠實如今超級多的數據中查找任何一個資源所消耗的時間都是相同的;
3.在任何可用狀況下,單緩衝機制能以不復制任何數據的方式完成讀寫操做,這回節約大量的CPU時鐘週期以及內存帶寬;
4.藉助於linux2.6及以上的OS中的splice()系統調用,Haproxy能夠實現零複製轉發;在linux3.5及以上的OS中還能夠實現零複製啓動;
5.內存分配器在固定大小的內存池中可實現即時內存分配,這更夠顯著減小建立一個會話的時長;
6.使用樹形存儲,使用的是做者本身開發的彈性二叉樹,實現了以O(log(N))的低開銷來保持計數器命令、保持運行隊列命令、管理輪詢以及最少鏈接隊列;
7.優化了HTTP首部分析功能,避免了在HTTP首部分析過程當中重讀任何內存區域;
8.減小了繁重的系統調用,大部分工做都在用戶空間完成,如時間讀取、緩衝聚合及文件描述符的啓用和禁用等;
Note:Haproxy的tcp層負載均衡是經過軟件模擬出來的,其實際的性能遠沒有LVS強,可是Haproxy配置簡單,使用方便,對於通常的企業級訪問量徹底是夠用的;
工做位置:
Haproxy能夠位於客戶端(Clients)與web server之間實現負載均衡,也能夠在位於web server與後端的app server之間實現負載均衡,還能夠位於app server與後端的數據庫之間實現動靜分離;
Haproxy的代理功能:
代理服務器通俗的說就是客戶端要訪問互聯網上的某些資源時不是本身直接去資源服務器上請求相應的資源,而是將本身的需求告訴本身的代理服務器,而後代理服務器代替客戶端去請求其須要的資源;這樣能夠增長真實客戶端的安全性,也能夠在代理服務器上作一些訪問策略,增長訪問性能,好比在代理服務器上增長緩存功能,當下次再訪問相同資源時,代理服務器就不用再去資源服務器上請求資源了,而是將本身的緩存直接響應給真實客戶端;那麼代理服務器是怎麼實現代理的呢?代理服務器首先會接收到客戶端的請求,而後對其進行分析,查看其要訪問的資源是什麼,而後根據分析結果從新構造數據包,將本身做爲客戶端再去請求相應資源,因此資源服務器看到的是代理服務器的地址,若是不在代理服務器上作相應的設置,資源服務器是沒法知道真實客戶端的ip地址的;
關於長鏈接:
長鏈接通常是指客戶端與服務器端在一段時間以內一直保持着鏈接狀態,這樣能夠避免頻繁的建立鏈接,而消耗更多的資源,畢竟鏈接的建立與拆除也是須要消耗資源的;可是有代理服務器的鏈接就與通常狀況的有些不一樣了,由於你要分清客戶端是與代理服務器保持長鏈接仍是經過代理服務器直接和後端資源服務器直接保持長鏈接呢!長鏈接通常都是應用在互聯網上的客戶端和服務器之間,用於減小服務器的負載,咱們這裏講述的Haproxy代理是位於資源服務器這一邊的,能夠理解成Haproxy是資源服務器組對外的出口,資源服務器爲內網中的主機,因此Haproxy與資源服務器能夠不使用長鏈接,主要是客戶端與Haproxy之間在須要時才啓用長鏈接(不是說Haproxy與資源服務器就不可使用長鏈接,根據須要啓用便可);
關於緩存:
在現今的互聯網上有一個說法就是cache is king,這足以說明緩存的重要性了,緩存能夠減小冗餘數據的傳輸、節省帶寬,緩解網絡瓶頸、下降對原始服務器的訪問壓力、下降了傳輸延遲等;
關於鏈接數:
Haproxy代理服務器同時可處理的鏈接數,會受linux中的端口號數量的限制,由於做爲http的代理,在接收到客戶端的請求後,會爲這個鏈接隨機分配一個端口號,用於與其創建鏈接,從而進行數據的傳輸,同時,代理服務器還要向後端的真正的服務器發起相關的請求,這就又須要一個端口號來創建鏈接,因此大致算一下,linux中一共有65535個端口,先後各分去一半,也就是說在滿載的時候Haproxy代理服務器最多也就能處理(65535/2)個鏈接,這仍是沒有去掉各類服務監聽使用的固定端口的狀況;這段內容只是爲了代表端口號對鏈接數的限制,在生產環境中是不會讓服務器同時處理三萬多個鏈接的,會致使服務器高負載,掛掉的;還有就是單個用戶默承認以打開的文件爲1024個,因此通常會將這個數字儘可能的調大一點,讓服務器能夠處理更多請求;由於在linux中一切皆文件,一個端口號就是一個文件(套接字文件);相比來講LVS就不受套接字數量的限制,由於LVS是在內核中直接處理的,無需端口號,這不是勸你用LVS,若是是中小型網站,併發量並很少的環境中使用LVS就會有種殺雞用牛刀的感受,再說了LVS在更高層的控制功能上比較弱小,好比LVS就不支持動靜分離;因此選擇哪一種軟件,由需求而定,適用就好;
Haproxy只能實現對http協議進行反向代理,本身不具備緩存功能,可是它支持對4層傳輸層基於tcp通訊的應用進行負載均衡;
評估負載均衡器性能的三要素:
會話率:單位時間內會話創建的速率;
會話併發能力:能夠保持多少個會話同時存在的能力;
數據率:數據的傳輸效率;
HAproxy安裝及配置:
安裝:
yum install haproxy
配置文件:
/etc/haproxy/haproxy.cfg
haproxy的配置文件分爲一下幾段:
global:全局配置段
defaults:默認配置段,能夠爲backend、frontend以及listen提供相同的默認配置參數;同一參數能夠在defaults中定義,也能夠在frontend、backed、以及listen中定義,可是在後者中定義參數優先級高於前者;
listen:直接指定監聽的端口和地址,不使用frontend和backend就能夠完成向後端進行調度;能夠經過此段定義haproxy的監控頁面
frontend:前端配置段,相似nginx中的server
backend:後端配置段,相似nginx中的upstream
Haproxy能夠經過在frontend中使用use_backed參數調用backend,來實現負載均衡;
簡單的例子:
須要三臺主機,一臺爲centos7做爲haproxy代理,另外兩臺爲centos6做爲web server,運行httpd服務;
centos7:
yum install haproxy
vim /etc/haproxy/haproxy.cfg
frontend main *:80
default_backend webserver
backend webserver
balance roundrobin
server clone1 192.168.80.131:80 check
server clone2 192.168.80.134:80 check
vim /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
local2.* /var/log/haproxy.log
systemctl restart rsyslog.service
systemctl start haproxy.service
centos6_1:
echo "<h1>clone1</h1>" > /var/www/html/index.html
service httpd start
centos6_2:
echo "<h1>clone2</h1>" > /var/www/html/index.html
service httpd start
在瀏覽器端鍵入cnetos7的IP地址訪問web服務進行測試;
參數詳解:
global:
log ip_addr log_level
定義日誌功能;haproxy的日誌功能是經過將日誌發送給日誌服務器進行記錄的,而不是像其餘服務同樣,直接記錄到日誌文件的;因此要想記錄haproxy的日誌,須要對/etc/rsyslog.conf進行相關配置:在配置文件中啓用$ModLoad imudp及$UDPServerRun 514後添加有關log_level的相關功能;
chroot /path/to/dir
定義根目錄,以安全方式運行;
maxconn conn_number
定義每一個進程所能接受的最大併發鏈接數;
daemon
定義服務做爲守護進程,在後臺運行
stats socket /var/lib/haproxy/stats
設置訪問stats狀態頁時,基於unix套接字進行訪問;
ulimit-n number
設定每一個進程所能打開的最大文件描述符,服務默認會自動進行設置;
spread-checks <0…50, in percent>
用於將對後端進行健康狀態檢測的時機進行分散,以防止形成瞬間擁塞現象;html
backend:
balance
指定調度算法:
動態:權重可動態調整
roundrobin:基於權重進行輪詢調度,每一個後端主機最多支持4128個鏈接;
leastconn:新的鏈接請求會被調度到後端具備最少鏈接數的服務器上;在由較長時間會話的場景中推薦使用;
靜態:權重不會實時生效
static-rr:基於權重進行輪詢調度,每一個後端主機支持的鏈接數量沒有限制;
source:將請求的源地址進行hash運算,而後除之後端服務器的總權重數,最後將結果調度到相應的服務器上;能夠將同一IP的客戶端始終調度到同一臺服務器上;可是當後端服務器的權重發生變化之後,就有可能會將以前同一IP的請求調度至其餘服務器上;
hdr (<name>):根據請求報文中指定的header(use_age、hostname等)進行調度,將指定header的值作hash計算,而後除之後端服務器的總權重,最後將鏈接調度到指定服務器;
全部跟hash有關的調度算法,都會受hash-type指定的類型影響,若是是map-based(默認)就是靜態算法,若是爲consistent就是動態算法;
server <name> <addr> [:port] [param*]:指定後端服務器地址;還能夠定義在listen中;
name:指定服務器的內部名稱,用於日誌查詢;
address:指定服務器的IP地址;
port:指定將鏈接請求調度至此服務器上的哪一個目標端口,未設定時使用客戶端請求時使用的端口;
param*:爲此服務器設定的參數,能夠實現特定功能;
backup:指定此服務器爲比用服務器,相似sorry server;
check:啓動對此處定義的後端服務器進行健康狀態檢查;
cookie [ rewrite | insert | prefix ] [ indirect ] [ nocache ]:能夠基於瀏覽器cookie實現session綁定;
例子:
backend webserver
balance roundrobin
cookie SERVERID insert nocache indirect
server clone1 192.168.80.131:80 check weight 1 cookie clone1
server clone2 192.168.80.134:80 check weight 2 cookie clone2
cookie <value>:當Haproxy代理服務器第一次接收到某客戶端發來的請求時,在爲其調度選擇後端服務器後會再爲其分發一個cookie,等下次這個客戶端再來請求時,會檢查其cooki值,若是匹配則直接將其調度至相關服務器上;相似於基於session的cookie綁定;
maxconn number:此服務器能都接收的併發鏈接的最大數量;
weight:定義服務器的權重;1-250
frontend:
bind [<addr>]:<port_range> [,…] :設置監聽的套接字,能夠是多個;
除了能夠用在frontend中,還能夠用在listen中;
addr:可爲主機名、IP地址,*表示全部主機;
port_range:能夠是單一端口號,也能夠是端口號列表;
mode {tcp|http}:指定實例同後端服務器之間運行的模式或協議,當實現內容交換時,前端和後端必須使用同一種模式,不然將沒法傳輸數據;
tcp:客戶端和服務器端之間建議一條全雙工的鏈接,而且不會對7層報文作任何的處理,一般用於SSL、SSH等場景;默認模式;
http:客戶端請求在通過Haproxy到達後端服務器時會進行7層的深度解析,而後再根據解析結果將請求調度至後端服務器上;
maxconn number:定義一個前端的額最大併發鏈接數;這個鏈接數的數量會經過調度算法分散到backend中定義的後端服務器上,因此設置這個數值時要考慮本身的後端服務器能夠承受多大的併發量;而且這個併發鏈接數不能夠超過global中設置的最大鏈接併發數;
default_backend:指定默認的後端服務器;
use_backend:指定使用的後端服務器;優先級比default_backend高;能夠添加條件語句「if」;格式爲:use_backend name if acl_rule_name
其餘參數:
capture request header <name> len <length>
捕獲請求報文最後一次出現時的header的完整值,用於在日誌中記錄額外信息;只能用在frontend和listen中;
name:要捕獲的header的名稱;
length:截取要保存的的頭部值的長度;
capture response header <name> len <length>
捕獲響應報文最後一次出現是的header的完整值,用於在日誌中記錄額外信息;只能用在frontend和listen中;
option httplog:當mode爲http時,記錄豐富的日誌信息; 可用於defaults、frontend、listen、backend中;
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
用於記錄真實的客戶端的地址,若是不設置,因爲Haproxy代理的存在,後端服務器日誌中記錄的來源地址都會是Haproxy的IP地址;可用於defaults、frontend、listen、backend中;
而且須要在後端服務器的web程序日誌中將」X-Forwarded-For」添加進去;
示例:LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
errorfile /path/to/file:定義錯誤頁面重定向,使用Haproxy主機本地文件進行響應;可用於defaults、frontend、listen、backend中;
errorloc|errorloc302 url:使用指定的url進行響應;響應狀態碼爲302,不適用於GET之外的其餘請求方法;可用於defaults、frontend、listen、backend中;
errorloc303 url:返回303狀態碼;可用於defaults、frontend、listen、backend中;
http-request { allow | deny | tarpit | auth [realm <realm>] } [ { if | unless } <condition> ]:設置關於七層的請求報文的訪問控制;可用於frontend、listen、backend中;
acl <aclname> <criterion> [flags] [operator] <value> :定義訪問控制列表;
aclname:指定acl的名稱
criterion:指定要檢查的屬性(條件),好比src、src_port等
flags:標誌位,目前haproxy支持三個標誌位:-i爲不區分value中模式的大小寫、-f爲從指定的文件中加載模式、--爲標記符的強制結束標誌;
value:acl測試條件支持的值有四種:
1.整數或整數範圍,僅支持使用正整數,且支持五種操做符:eq、ge、gt、le、lt;
2.字符串:支持使用」-i」忽略字符大小寫,支持使用」\」進行轉移;
3.正則表達式:其機制相似字符串匹配機制;
4.IP地址及網絡地址;
Note:同一個acl中能夠定義多個測試條件,這些測試條件能夠由邏輯操做符指定其關係,條件間的組合測試關係有三種:與(默認)、或、非;
詳情請查看:http://cbonte.github.io/haproxy_dconv/1.5/configuration.html#7
http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4
haproxy的狀態監控頁:
能夠在listen和backend中設置;
參數選項:
stats enable:啓用haproxy的統計報告;
stats uri /path/to/file:設置統計報告頁的位置
stats realm 「String」:設置登陸時的提示信息
stats auth stats_user:stats_passwd:指定登陸的用戶名和密碼
stats hide-version:隱藏haproxy的版本信息;
stats scope . :指定stats的做用域;」.」爲當前(自身)做用域的意思;
stats admin if TRUE:當驗證經過時,啓動管理員在統計狀態頁中的管理權限(能夠直接設置讓backend中的server下線或者上線);
例子:
1.listen statistics
bind *:12138
stats enable
stats hide-version
在瀏覽器輸入http://192.168.80.138:12138/haproxy?stats便可查看統計狀態頁;
2.listen statistics
bind *:12138
stats enable
stats hide-version
stats scope .
stats uri /haproxy-stats
stats auth guowei:admin
stats realm "Haproxy\ stats page"
在瀏覽器輸入http://192.168.80.138:12138/haproxy-stats後會提示輸入用戶名密碼,按要求輸入便可查看統計狀態頁;
官方文檔:http://cbonte.github.io/haproxy-dconv/1.5/configuration.html前端
注:根據馬哥視頻作的學習筆記,若有錯誤,歡迎指正;侵刪;
linux