1 HAproxy介紹
1.1 Haproxy是一個開源的高性能的反向代理或者說是負載均衡服務軟件之一,它支持雙機熱備、虛擬主機、基於TCP和HTTP應用代理等功能。其配置簡單,並且擁有很好的對服務器節點的健康檢查功能(至關於keepalived健康檢查),當其代理的後端服務器出現故障時,Haproxy會自動的將該故障服務器摘除,當服務器的故障恢復後Haproxy還會自動將RS服務器上線
1.2 Haproxy特別適用與那些訪問量很大。但又須要會話保持或七層應用的業務。Haproxy運行在普通的服務器硬件上,僅僅進行簡單的優化就能夠支持數以萬計的併發鏈接。而且它的運行模式使得它能夠很簡單安全的整合到各類網站的架構中,同時使得應用服務器不會暴露到網絡中
1.3 HAProxy 實現了一種事件驅動、單一進程模型,此模型支持很是大的併發鏈接數。多進程或多線程模型受內存限制 、系統調度器限制以及無處不在的鎖限制,不多能處理數千併發鏈接。事件驅動模型由於在有更好的資源和時間管理的用戶端(User-Space) 實現全部這些任務,因此沒有這些問題。此模型的弊端是,在多核系統上,這些程序一般擴展性較差。這就是爲何他們必須進行優化以 使每一個CPU時間片(Cycle)作更多的工做
1.4 HAProxy 支持鏈接拒絕 : 由於維護一個鏈接的打開的開銷是很低的,有時咱們很須要限制***蠕蟲(attack bots),也就是說限制它們的鏈接打開從而限制它們的危害。 這個已經爲一個陷於小型DDoS***的網站開發了並且已經拯救了不少站點,這個優勢也是其它負載均衡器沒有的
1.5 HAProxy 支持全透明代理(已具有硬件防火牆的典型特色): 能夠用客戶端IP地址或者任何其餘地址來鏈接後端服務器. 這個特性僅在Linux 2.4/2.6內核打了cttproxy補丁後纔可使用. 這個特性也使得爲某特殊服務器處理部分流量同時又不修改服務器的地址成爲可能
1.6 Haproxy軟件引入了frontend,backend的功能,frontend(acl規則匹配)能夠運維管理人員根據任意HTTP請求頭作規則匹配,而後把請求定向到相關的backend(server pools等待前端把請求轉過來的服務器組)。經過frontend和backup,咱們能夠很容易的實現haproxy的7層代理功能,haproxy是一款不可多得的優秀代理服務軟件
1.7 Haproxy支持兩種主要代理模式:第一個是4層tcp代理(例如:可用於郵件服務內部協議通訊服務器、Mysql服務等)。第二個是7層代理(如HTTP代理)。在4層tcp代理模式下,Haproxy僅在客戶端和服務器之間雙向轉發流量。可是在7層模式下Haproxy會分析應用層協議,而且能經過運行、拒絕、交換、增長、修改或者刪除請求(request)或者回應(reponse)裏指定內容來控制協議javascript
2 Haproxy解決方案拓撲圖
2.1 Haproxy L4負載均衡應用架構拓撲
Haproxy軟件的四層tcp代理應用很是優秀,配置很是簡單方便,比LVS和Nginx要方便不少,由於不須要在RS端執行腳本便可實現應用代理。
說明:因爲Haproxy採用的是NAT模式,數據包來去都會通過Haproxy,所以,在流量特別大的狀況下,其性能不如LVS。
在通常的中小型公司,建議採用haproxy作負載均衡,而不要使用LVS或者Nginx。
所謂的四層就是ISO參考模型中的第四層。四層負載均衡也稱爲四層交換機,它主要是經過分析IP層及TCP/UDP層的流量實現的基於IP加端口的負載均衡。常見的基於四層的負載均衡器有LVS、F5等。
以常見的TCP應用爲例,負載均衡器在接收到第一個來自客戶端的SYN請求時,會經過設定的負載均衡算法選擇一個最佳的後端服務器,同時將報文中目標IP地址修改成後端服務器IP,而後直接轉發給該後端服務器,這樣一個負載均衡請求就完成了。從這個過程來看,一個TCP鏈接是客戶端和服務器直接創建的,而負載均衡器只不過完成了一個相似路由器的轉發動做。在某些負載均衡策略中,爲保證後端服務器返回的報文能夠正確傳遞給負載均衡器,在轉發報文的同時可能還會對報文原來的源地址進行修改。整個過程下圖所示php
2.2 Haproxy L7負載均衡應用架構拓撲
Haproxy軟件的最大優勢在於其7層的根據URL請求頭應用過濾的功能,通常用在LVS軟件的下一層,或者像官方推薦的能夠掛在硬件負載均衡NS、F5下使用
七層負載均衡器也稱爲七層交換機,位於OSI的最高層,即應用層,此時負載均衡器支持多種應用協議,常見的有HTTP、FTP、SMTP等。七層負載均衡器能夠根據報文內容,再配合負載均衡算法來選擇後端服務器,所以也稱爲「內容交換器」。好比,對於Web服務器的負載均衡,七層負載均衡器不但能夠根據「IP+端口」的方式進行負載分流,還能夠根據網站的URL、訪問域名、瀏覽器類別、語言等決定負載均衡的策略。例如,有兩臺Web服務器分別對應中英文兩個網站,兩個域名分別是A、B,要實現訪問A域名時進入中文網站,訪問B域名時進入英文網站,這在四層負載均衡器中幾乎是沒法實現的,而七層負載均衡能夠根據客戶端訪問域名的不一樣選擇對應的網頁進行負載均衡處理。常見的七層負載均衡器有HAproxy、Nginx等。
這裏仍以常見的TCP應用爲例,因爲負載均衡器要獲取到報文的內容,所以只能先代替後端服務器和客戶端創建鏈接,接着,才能收到客戶端發送過來的報文內容,而後再根據該報文中特定字段加上負載均衡器中設置的負載均衡算法來決定最終選擇的內部服務器。縱觀整個過程,七層負載均衡器在這種狀況下相似於一個代理服務器。整個過程以下圖所示css
對比四層負載均衡和七層負載均衡運行的整個過程,能夠看出,在七層負載均衡模式下,負載均衡器與客戶端及後端的服務器會分別創建一次TCP鏈接,而在四層負載均衡模式下,僅創建一次TCP鏈接。由此可知,七層負載均衡對負載均衡設備的要求更高,而七層負載均衡的處理能力也必然低於四層模式的負載均衡html
3 安裝haproxy
3.1 yum -y install haproxy
rpm -qi haproxy (版本爲1.5.4)
rpm -ql haproxy
/etc/haproxy
/etc/haproxy/haproxy.cfg(haproxy的配置文件)
/etc/logrotate.d/haproxy
/etc/sysconfig/haproxy
3.2 詳細的配置文件
haproxy配置文件分爲兩部分組成:全局設定和代理的設定,共分爲五段:obal,default,frontend,backend,listen
3.2.1 配置文件格式
haproxy的配置處理3類主要參數來源:
最優先處理的命令行參數
"global"配置段,用於設定全局配置參數
proxy相關配置段,如「default」、「listen」、「frontend」和「backend」
3.2.2 時間格式
一些包含了值的參數表示時間,如超長時間。這些值通常以毫秒爲單位,但也可使用其餘的時間單位後綴
us: 微秒(microseconds),即1/1000000秒;
ms: 毫秒(milliseconds),即1/1000秒;
s: 秒(seconds);
m: 分鐘(minutes);
h:小時(hours);
d: 天(days);
3.2.3 全局的配置
進程管理及安全相關的參數前端
性能調整相關的參數
– maxconn <number>:設定每一個haproxy進程所接受的最大併發鏈接數,其等同於命令行選項「-n」;「ulimit -n」自動計算的結果正是參照此參數設定的;
– maxpipes <number>:haproxy使用pipe完成基於內核的tcp報文重組,此選項則用於設定每進程所容許使用的最大pipe個數;每一個pipe會打開兩個文件描述符,所以,「ulimit -n」自動計算時會根據須要調大此值;默認爲maxconn/4,其一般會顯得過大;
– noepoll:在Linux系統上禁用epoll機制;
– nokqueue:在BSE系統上禁用kqueue機制;
– nopoll:禁用poll機制;
– nosepoll:在Linux禁用啓發式epoll機制;
– nosplice:禁止在Linux套接字上使用內核tcp重組,這會致使更多的recv/send系統調用;不過,在Linux 2.6.25-28系列的內核上,tcp重組功能有bug存在;
– spread-checks <0..50, in percent>:在haproxy後端有着衆多服務器的場景中,在精確的時間間隔後統一對衆服務器進行健康情況檢查可能會帶來意外問題;此選項用於將其檢查的時間間隔長度上增長或減少必定的隨機時長;
– tune.bufsize <number>:設定buffer的大小,一樣的內存條件小,較小的值可讓haproxy有能力接受更多的併發鏈接,較大的值可讓某些應用程序使用較大的cookie信息;默認爲16384,其能夠在編譯時修改,不過強烈建議使用默認值;
– tune.chksize <number>:設定檢查緩衝區的大小,單位爲字節;更大的值有助於在較大的頁面中完成基於字符串或模式的文本查找,但也會佔用更多的系統資源;不建議修改;
– tune.maxaccept <number>:設定haproxy進程內核調度運行時一次性能夠接受的鏈接的個數,較大的值能夠帶來較大的吞吐率,默認在單進程模式下爲100,多進程模式下爲8,設定爲-1能夠禁止此限制;通常不建議修改;
– tune.maxpollevents <number>:設定一次系統調用能夠處理的事件最大數,默認值取決於OS;其值小於200時可節約帶寬,但會略微增大網絡延遲,而大於200時會下降延遲,但會稍稍增長網絡帶寬的佔用量;
– tune.maxrewrite <number>:設定爲首部重寫或追加而預留的緩衝空間,建議使用1024左右的大小;在須要使用更大的空間時,haproxy會自動增長其值;
– tune.rcvbuf.client <number>:
– tune.rcvbuf.server <number>:設定內核套接字中服務端或客戶端接收緩衝的大小,單位爲字節;強烈推薦使用默認值;
– tune.sndbuf.client:
– tune.sndbuf.server:java
Debug相關的參數node
超時時長
timeout http request :在客戶端創建鏈接但不請求數據時,關閉客戶端鏈接
timeout queue :等待最大時長
timeout connect: 定義haproxy將客戶端請求轉發至後端服務器所等待的超時時長
timeout client:客戶端非活動狀態的超時時長
timeout server:客戶端與服務器端創建鏈接後,等待服務器端的超時時長,
timeout http-keep-alive :定義保持鏈接的超時時長
timeout check:健康狀態監測時的超時時間,太短會誤判,過長資源消耗
maxconn :每一個server最大的鏈接數mysql
http-server-close : 在使用長鏈接時,爲了不客戶端超時沒有關閉長鏈接,此功能可使服務器端關閉長鏈接
redispatch: 在使用基於cookie定向時,一旦後端某一server宕機時,會將會話從新定向至某一上游服務器,必須使用 的選項web
實現訪問控制
http-request:7層過濾
tcp-request content:tcp層過濾,四層過濾
3.2.4 代理
代理相關的配置能夠以下配置段中正則表達式
The default
values are the following ones :
cookie <value>:爲指定server設定cookie值,此處指定的值將在請求入站時被檢查,第一次爲此值挑選的server將在後續的請求中被選中,其目的在於實現持久鏈接的功能;
maxconn <maxconn>:指定此服務器接受的最大併發鏈接數;若是發往此服務器的鏈接數目高於此處指定的值,其將被放置於請求隊列,以等待其它鏈接被釋放;
haproxy 有n個進程,每一個支持m個鏈接,後端有x個服務器,每一個最大支持y個鏈接,則 nm <= xy,若是後端服務器支持排隊,則nm <= x(y+z),z爲每一個服務器的排隊隊列
maxqueue <maxqueue>:設定請求隊列的最大長度;
observe <mode>:經過觀察服務器的通訊情況來斷定其健康狀態,默認爲禁用,其支持的類型有「layer4」和「layer7」,「layer7」僅能用於http代理場景;
redir <prefix>:啓用重定向功能,將發往此服務器的GET和HEAD請求均以302狀態碼響應;須要注意的是,在prefix後面不能使用/,且不能使用相對地址,以避免形成循環;例如:
server srv1 172.16.100.6:80 redir http://imageserver.feiyu.com check
weight <weight>:權重,默認爲1,最大值爲256,0表示不參與負載均衡(不被調度);
檢查方法:
option httpchk
option httpchk
option httpchk
option httpchk :不能用於frontend段,例如:
backend https_relay
mode tcp
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www.feiyu.com
server apache1 192.168.1.1:443 check port 80
使用案例:
server first 172.16.100.7:1080 cookie first check inter 1000
server second 172.16.100.8:1080 cookie second check inter 1000
4.9 capture request header
capture request header <name> len <length>
捕獲並記錄指定的請求首部最近一次出現時的第一個值,僅能用於「frontend」和「listen」區段。捕獲的首部值使用花括號{}括起來後添加進日誌中。若是須要捕獲多個首部值,它們將以指定的次序出如今日誌文件中,並以豎線「|」做爲分隔符。不存在的首部記錄爲空字符串,最常須要捕獲的首部包括在虛擬主機環境中使用的「Host」、上傳請求首部中的「Content-length」、快速區別真實用戶和網絡機器人的「User-agent」,以及代理環境中記錄真實請求來源的「X-Forward-For」。
<name>:要捕獲的首部的名稱,此名稱不區分字符大小寫,但建議與它們出如今首部中的格式相同,好比大寫首字母。須要注意的是,記錄在日誌中的是首部對應的值,而非首部名稱。
<length>:指定記錄首部值時所記錄的精確長度,超出的部分將會被忽略。
能夠捕獲的請求首部的個數沒有限制,但每一個捕獲最多隻能記錄64個字符。爲了保證同一個frontend中日誌格式的統一性,首部捕獲僅能在frontend中定義
4.10 capture request header
capture response header <name> len <length>
捕獲並記錄響應首部,其格式和要點同請求首部
4.11 stats enable
啓用基於程序編譯時默認設置的統計報告,不能用於「frontend」區段。只要沒有另外的其它設定,它們就會使用以下的配置:
5 ACL
haproxy的ACL用於實現基於請求報文的首部、響應報文的內容或其它的環境狀態信息來作出轉發決策,這大大加強了其配置彈性。其配置法則一般分爲兩步,首先去定義ACL,即定義一個測試條件,然後在條件獲得知足時執行某特定的動做,如阻止請求或轉發至某特定的後端。定義ACL的語法格式以下。
acl <aclname> <criterion> [flags] [operator] <value> ...
<aclname>:ACL名稱,區分字符大小寫,且其只能包含大小寫字母、數字、-(鏈接線)、_(下劃線)、.(點號)和:(冒號);haproxy中,acl能夠重名,這能夠把多個測試條件定義爲一個共同的acl;
<criterion>:測試標準,即對什麼信息發起測試;測試方式能夠由[flags]指定的標誌進行調整;而有些測試標準也能夠須要爲其在以前指定一個操做符[operator];
[flags]:目前haproxy的acl支持的標誌位有3個:
-i:不區分中模式字符的大小寫;
-f:從指定的文件中加載模式;
--:標誌符的強制結束標記,在模式中的字符串像標記符時使用;
<value>:acl測試條件支持的值有如下四類:
整數或整數範圍:如1024:65535表示從1024至65535;僅支持使用正整數(若是出現相似小數的標識,其爲一般爲版本測試),且支持使用的操做符有5個,分別爲eq、ge、gt、le和lt;
字符串:支持使用「-i」以忽略字符大小寫,支持使用「\」進行轉義;若是在模式首部出現了-i,能夠在其以前使用「–」標誌位;
正則表達式:其機制類同字符串匹配;
IP地址及網絡地址;
同一個acl中能夠指定多個測試條件,這些測試條件須要由邏輯操做符指定其關係。條件間的組合測試關係有三種:「與」(默認即爲與操做)、「或」(使用「||」操做符)以及「非」(使用「!」操做符)
5.1 經常使用的測試標準(criteria)
5.1.1 be_sess_rate
be_sess_rate(backend)<integer>
用於測試指定的backend上會話建立的速率(即每秒建立的會話數)是否知足指定的條件;經常使用於在指定backend上的會話速率太高時將用戶請求轉發至另外的backend,或用於阻止***行爲。例如:
backend dynamic
mode http
acl being_scanned be_sess_rate gt 50
redirect location /error_pages/denied.html if being_scanned
5.1.2 fe_sess_rate
fe_sess_rate(frontend)<integer>
用於測試指定的frontend(或當前frontend)上的會話建立速率是否知足指定的條件;經常使用於爲frontend指定一個合理的會話建立速率的上限以防止服務被濫用。例以下面的例子限定入站郵件速率不能大於50封/秒,全部在此指定範圍以外的請求都將被延時50毫秒
frontend mail
bind :25
mode tcp
maxconn 500
acl too_fast fe_sess_rate ge 50
tcp-request inspect-delay 50ms
tcp-request content accept if ! too_fast
tcp-request content accept if WAIT_END
5.1.3 hdr<string>
hdr(header)<string>
用於測試請求報文中的全部首部或指定首部是否知足指定的條件;指定首部時,其名稱不區分大小寫,且在括號「()」中不能有任何多餘的空白字符。測試服務器端的響應報文時可使用shdr()。例以下面的例子用於測試首部Connection的值是否爲close
hdr(connection) -i close
5.1.4 method <string>
method<string>
測試HTTP請求報文中使用的方法
5.1.5 path_beg <string>
用於測試請求的URL是否以指定的模式開頭。下面的例子用於測試URL是否以/static、/images、/javascript或/stylesheets頭
acl url_static path_beg -i /static /images /javascript /stylesheets
5.1.6 path_end <string>
用於測試請求的URL是否以<string>指定的模式結尾。例如,下面的例子用戶測試URL是否以jpg、gif、png、css或js結尾
acl url_static path_end -i .jpg .gif .png .css .js
5.1.7 hdr_beg <string>
用於測試請求報文的指定首部的結尾部分是否符合<string>指定的模式
6 配置案例
前端調度器IP:192.168.1.210
後端應用服務器IP: 192.168.1.111 和 192.168.1.112
定義獨立日誌文件
[root@node1 haproxy]# vim /etc/rsyslog.conf #爲其添加日誌功能
$ModLoad imudp
$UDPServerRun 514 ------>啓動udp,啓動端口後將做爲服務器工做
$ModLoad imtcp
$InputTCPServerRun 514 ------>啓動tcp監聽端口
local2.* /var/log/haproxy.log
[root@node1 haproxy]# service rsyslog restar
[root@LB haproxy]# vim haproxy.cfg
log 127.0.0.1 local2 --------->在global端中添加此行
一個最簡單的http服務的配置
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
frontend webser #webser爲名稱
option forwardfor
bind :80
default_backend app
backend app
balance roundrobin #使擁roundrobin 算法
server app1 192.168.1.111:80 check
server app2 192.168.1.112:80 check
haproxy統計頁面的輸出機制
frontend webser
log 127.0.0.1 local3
option forwardfor
bind :80
default_backend app
backend app
cookie node insert nocache
balance roundrobin
server app1 192.168.1.111:80 check cookie node1 intval 2 rise 1 fall 2
server app2 192.168.1.112:80 check cookie node2 intval 2 rise 1 fall 2
server backup 127.0.0.1:8010 check backup
listen statistics
bind :8009 # 自定義監聽端口
stats enable # 啓用基於程序編譯時默認設置的統計報告
stats auth admin:admin # 統計頁面用戶名和密碼設置
stats uri /admin?stats # 自定義統計頁面的URL,默認爲/haproxy?stats
stats hide-version # 隱藏統計頁面上HAProxy的版本信息
stats refresh 30s # 統計頁面自動刷新時間
stats admin if TRUE #若是認證經過就作管理功能,能夠管理後端的服務器
stats realm Hapadmin # 統計頁面密碼框上提示文本,默認爲Haproxy\ Statistics
動靜分離示例
frontend webservs
bind :80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js .html
acl url_php path_end -i .php
acl host_static hdr_beg(host) -i img. imgs. video. videos. ftp. image. download.
use_backend static if url_static or host_static
use_backend dynamic if url_php
default_backend dynamic
backend static
balance roundrobin
server node1 192.168.1.111:80 check maxconn 3000
backend dynamic
balance roundrobin
server node2 192.168.1.112:80 check maxconn 1000
http服務器配置完整示例
#---------------------------------------------------------------------
#---------------------------------------------------------------------
global
#
#
#
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 30000
listen stats
mode http
bind 0.0.0.0:1080
stats enable
stats hide-version
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth admin:admin
stats admin if TRUE
frontend http-in
bind *:80
mode http
log global
option httpclose
option logasap #不等待響應結束就記錄日誌,表示提早記錄日誌,通常日誌會記錄響應時長,此不記錄響應時長
option dontlognull #不記錄空信息
capture request header Host len 20 #記錄請求首部的前20個字符
capture request header Referer len 60 #referer跳轉引用,就是上一級
default_backend servers
frontend healthcheck
bind :1099 #定義外部檢測機制
mode http
option httpclose
option forwardfor
default_backend servers
backend servers
balance roundrobin
server websrv1 192.168.1.111:80 check maxconn 2000
server websrv2 192.168.1.112:80 check maxconn 2000
負載均衡MySQL服務的配置示例
#---------------------------------------------------------------------
#---------------------------------------------------------------------
global
#
#
#
#log 127.0.0.1 local2chroot /var/lib/haproxypidfile /var/run/haproxy.pidmaxconn 4000user haproxygroup haproxydaemondefaultsmode tcplog globaloption httplogoption dontlognullretries 3timeout http-request 10stimeout queue 1mtimeout connect 10stimeout client 1mtimeout server 1mtimeout http-keep-alive 10stimeout check 10smaxconn 600listen statsmode httpbind 0.0.0.0:1080stats enablestats hide-versionstats uri /haproxyadmin?statsstats realm Haproxy\ Statisticsstats auth admin:adminstats admin if TRUEfrontend mysqlbind *:3306mode tcplog globaldefault_backend mysqlserversbackend mysqlserversbalance leastconnserver dbsrv1 192.168.1.111:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300server dbsrv2 192.168.1.112:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300