在日常生活中,http主要用於做爲公司的正向代理,通過SNAT技術爲互聯網節省了很多的IP地址,相反haproxy是作爲反向代理,接收普通用戶的請求。代理的作用主要有訪問控制、web緩存(加速)、反向代理、內容路由(根據流量及內容類型等條件將請求轉發至特定的服務器)、轉碼器,以及在代理服務器上添加Via首部,用於分析經過的路由等作用。目前haproxy的版本主要有兩個,一個爲1.4,特點是能夠提供較好的彈性,還有一個版本是1.3的版本,其特性爲內容交換以及超強的負載,都是衍生以1.2版本。Haproxy是http協議的反向代理,即七層反向代理,不過在tcp層支持LB。
在Centos6.4版本後,就支持直接使用yum安裝。
安裝生成的:
配置文件:/etc/haproxy/haproxy.cfg
服務腳本:/etc/rc.d/init.d/haproxy
主程序:/usr/sbin/haproxy
在haproxy中定義反向:
frontend:定義前端服務;
backend:定義後端服務;
listen:用於定義前端的frontend以及後端的backend,而且還是一對一的對應;
default:定義默認配置;
在haproxy中日誌需要啓用纔會生成,在haproxy的主配置文件中有如下一行指令,是用於定義啓用日誌的:
首先定義日誌文件:
[root@node2 ~]# vim /etc/rsyslog.conf
此項的啓用,是使用udp監聽:
然後定義日誌位置:
然後重啓日誌服務就會生成haproxy的日誌:
示例:定義一個簡單的服務代理:
在配置中定義後端服務爲appserver,以及兩個後端服務器,一個後端主機位172.16.90.2還有一個172.16.90.3。
[
root@node0 ~]# vim /etc/haproxy/haproxy.cfg
而後,後端服務器啓動http服務,就能得到代理的後面服務器的兩個測試頁面:
下面說下全局配置中的一些參數:
“global”配置中的參數爲進程級別的參數,且通常與其運行的OS相關。
* 進程管理及安全相關的參數
- chroot <jail dir>:修改haproxy的工作目錄至指定的目錄並在放棄權限之前執行chroot()操作,可 以提升haproxy的安全級別,不過需要注意的是要確保指定的目錄爲空目錄且 任何用戶均不能有寫權限;
- daemon:讓haproxy以守護進程的方式工作於後臺,其等同於“-D”選項的功能,當然,也可以 在命令行中以“-db”選項將其禁用;
- gid <number>:以指定的GID運行haproxy,建議使用專用於運行haproxy的GID,以免因權限問題帶 來風險;
- group <group name>:同gid,不過指定的組名;
- log <address> <facility> [max level [min level]]:定義全局的syslog服務器,最多可以定義兩個;
- log-send-hostname [<string>]:在syslog信息的首部添加當前主機名,可以爲“string”指定的名稱, 也可以缺省使用當前主機名;
- nbproc <number>:指定啓動的haproxy進程的個數,只能用於守護進程模式的haproxy;默認只啓 動一個進程,鑑於調試困難等多方面的原因,一般只在單進程僅能打開少數文 件描述符的場景中才使用多進程模式;
- pidfile:pid文件,即進程文件;
- uid:以指定的UID身份運行haproxy進程;
- ulimit-n:設定每進程所能夠打開的最大文件描述符數目,默認情況下其會自動進行計算,因此不 推薦修改此選項;
- user:同uid,但使用的是用戶名;
- stats:
- node:定義當前節點的名稱,用於HA場景中多haproxy進程共享同一個IP地址時;
- description:當前實例的描述信息;
性能調整相關的參數
- maxconn <number>:設定每個haproxy進程所接受的最大併發連接數,其等同於命令行選項 “- n”;“ulimit -n”自動計算的結果正是參照此參數設定的;
- maxpipes <number>:haproxy使用pipe完成基於內核的tcp報文重組,此選項則用於設定每進程所 允許使用的最大pipe個數;每個pipe會打開兩個文件描述符,因 此,“ulimit -n”自動計算時會根據需要調大此值;默認爲maxconn/4,其通 常會顯得過大;
- noepoll:在Linux系統上禁用epoll機制;
- nokqueue:在BSD系統上禁用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<number>:設定內核套接字中客戶端發送緩衝的大小,單位爲字節; 強烈推薦使用默認值;
- tune.sndbuf.server<number>:設定內核套接字中服務端發送緩衝的大小,單位爲字節; 強烈推薦使用默認值;
代理相關的配置可以如下配置段中。
- defaults <name>
- frontend <name>
- backend <name>
- listen <name>
“defaults”段用於爲所有其它配置段提供默認參數,這配置默認配置參數可由下一個“defaults”所重新設定。
“frontend”段用於定義一系列監聽的套接字,這些套接字可接受客戶端請求並與之建立連接。
“backend”段用於定義一系列“後端”服務器,代理將會將對應客戶端的請求轉發至這些服務器。
“listen”段通過關聯“前端”和“後端”定義了一個完整的代理,通常只對TCP流量有用。
所有代理的名稱只能使用大寫字母、小寫字母、數字、-(中線)、_(下劃線)、.(點號)和:(冒號)。此外,ACL名稱會區分字母大小寫。
代理參數:
balance:指明調度算法,算法可分爲動態(權重可動態調整)和靜態(調整權重不會實 時生效)兩類
roundrobin:基於權重進行輪叫,在服務器的處理時間保持均勻分佈時,這是最平衡、最 公平的算法。此算法是動態的,這表示其權重可以在運行時進行調整,不 過,在設計上,每個後端服務器僅能最多接受4128個連接;
static-rr:基於權重進行輪叫,與roundrobin類似,但是爲靜態方法,在運行時調整其服務 器權重不會生效;不過,其在後端服務器連接數上沒有限制;
leastconn: 新的連接請求被派發至具有最少連接數目的後端服務器;在有着較長時間會話 的場景中推薦使用此算法,如LDAP、SQL等,其並不太適用於較短會話的應用 層協議,如HTTP;此算法是動態的,可以在運行時調整其權重source:不建議 使用;
source:將請求的源地址進行hash運算,並由後端服務器的權重總數相除後派發至某匹 配的服務器;這可以使得同一個客戶端IP的請求始終被派發至某特定的服務 器;不過,當服務器權重總數發生變化時,如某服務器宕機或添加了新的服務 器,許多客戶端的請求可能會被派發至與此前請求不同的服務器;常用於負載 均衡無cookie功能的基於TCP的協議;其默認爲靜態,不過也可以使用hash-type 修改此特性;;
hash-type:取決取模法
map-based: 靜態;
consistent: 動態;
uri:對URI的左半部分(“問題”標記之前的部分)或整個URI進行hash運算,並由服務器的總 權重相除後派發至某匹配的服務器;這可以使得對同一個URI的請求總是被派發至某 特定的服務器,除非服務器的權重總數發生了變化;此算法常用於代理緩存或反病 毒代理以提高緩存的命中率;需要注意的是,此算法僅應用於HTTP後端服務器場 景;其默認爲靜態算法,不過也可以使用hash-type修改此特性;建議consistent的取 模法: 動態;
scheme://host:port/path/to/some_resource? #
url_param: 通過<argument>爲URL指定的參數在每個HTTP GET請求中將會被檢索;如果找到 了指定的參數且其通過等於號“=”被賦予了一個值,那麼此值將被執行hash運 算並被服務器的總權重相除後派發至某匹配的服務器;此算法可以通過追蹤請 求中的用戶標識進而確保同一個用戶ID的請求將被送往同一個特定的服務器, 除非服務器的總權重發生了變化;如果某請求中沒有出現指定的參數或其沒有 有效值,則使用輪叫算法對相應請求進行調度;此算法默認爲靜態的,不過其 也可以使用hash-type修改此特性;建議consistent的取模法: 動態;
hdr(<name>):對於每個HTTP請求,通過<name>指定的HTTP首部將會被檢索;如果相應的 首部沒有出現或其沒有有效值,則使用輪叫算法對相應請求進行調度;其 有一個可選選項“use_domain_only”,可在指定檢索類似Host類的首部時僅 計算域名部分(比如通過www.magedu.com來說,僅計算magedu字符串的 hash值)以降低hash算法的運算量;此算法默認爲靜態的,不過其也可以使 用hash-type修改此特性;
header(host)
rdp-cookie
rdp-cookie(name)
default_backend <backend>:用於frontend中,用於指明爲請求提供服務的backend;
use_backend <backend> [{if | unless} <condition>]:條件式後端指定; <condition>由ACL定義的;
默認的配置文件中:
server <name> <address>[:[port]] [param*]
<address>:ipv4或ipv6;
[param*]:
check:啓用對server的健康狀態檢測功能;tcp層的監測;補充類的參數:
inter:時間間隔
rise:上線前的成功檢查次數
fall:下線前的失敗檢查次數
cookie:分配給server的cookie信息;
disabled:設置服務器爲“禁用”狀態;
maxconn:最大併發連接數;
maxqueue:等待隊列最大長度;0表示無上限;
minconn:最少併發連接數;
weight:權重;
例:
bind
bind [<address>]:<port_range> [, ...]
bind [<address>]:<port_range> [, ...] interface <interface>
此指令僅能用於frontend和listen區段,用於定義一個或幾個監聽的套接字。
<address>:可選選項,其可以爲主機名、IPv4地址、IPv6地址或*;省略此選項、將其指定爲*或0.0.0.0時,將監聽當前系統的所有IPv4地址;
<port_range>:可以是一個特定的TCP端口,也可是一個端口範圍(如5005-5010),代理服務器將通過指定的端口來接收客戶端請求;需要注意的是,每組監聽的套接字<address:port>在同一個實例上只能使用一次,而且小於1024的端口需要有特定權限的用戶才能使用,這可能需要通過uid參數來定義;
<interface>:指定物理接口的名稱,僅能在Linux系統上使用;其不能使用接口別名,而僅能使用物理接口名稱,而且只有管理有權限指定綁定的物理接口;
mode: 指明haproxy代理模式,默認爲tcp:
tcp:實例運行於純TCP模式,在客戶端和服務器端之間將建立一個全雙工的連接,且不會 對7層報文做任何類型的檢查;此爲默認模式,通常用於SSL、SSH、SMTP等應用; http:實例運行於HTTP模式,客戶端請求在轉發至後端服務器之前將被深度分析,所有不 與RFC格式兼容的請求都會被拒絕;
健康檢查方法:
option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>:不能用於frontend段,例如:
backend https_relay
mode tcp
option httpchk OPTIONS * HTTP/1.1\r\nHost:\www.magedu.com
server apache1 192.168.1.1:443 check port 80
stats enable
啓用基於程序編譯時默認設置的統計報告,不能用於“frontend”區段。只要沒有另外的其它設定,它們就會使用如下的配置:
- stats uri : /haproxyadmin?stats 改變路徑,更改後訪問路徑會改變
- stats realm : "\HAProxy\ Statistics" 提示信息
- stats auth : no authentication
- stats scope : no restriction
-stats hide-version 隱藏版本信息;
-stats admin { if | unless } <cond>
在指定的條件滿足時啓用統計報告頁面的管理級別功能,它允許通過web接口啓用或禁用服務器,不過,基於安全的角度考慮,統計報告頁面應該儘可能爲只讀的。此外,如果啓用了HAProxy的多進程模式,啓用此管理級別將有可能導致異常行爲。
backend
stats_localhost
stats enable
stats admin if LOCALHOST
backend
stats_auth
stats enable
stats auth haproxyadmin:password
stats admin if TRUE
例:
儘管“stats enable”一條就能夠啓用統計報告,但還是建議設定其它所有的參數,以免其依賴於默認設定而帶來非期後果。下面是一個配置案例。
backend public_www
server websrv1 172.16.100.11:80
stats enable
stats hide-version
stats scope .
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth statsadmin:password
stats auth statsmaster:password
haproxy cookie sticky:基於cookie的粘性,綁定服務器
cookie:Enable cookie-based persistence in a backend.
具體實現方式:
backend appsrvs
balance roundrobin
option httpchk
cookie SERVERID insert indirect nocache (以cookie名 SERVERID來插入web信息,nocache表示不緩存敏感數據)
server web1 172.16.100.7:80 check inter 2 rise 1 fall 3 cookie web1
server web2 172.16.100.8:80 check inter 2 rise 1 fall 3 cookie web2
option選項:
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
定義轉發首部,即轉發真正的客戶端首部到服務器端;可以用於frontend、backend、default、listen
Enable insertion of the X-Forwarded-For header to requests sent to servers
例:在haproxy服務器上,定義在backend中,添加option forwardfor;
更改後端上游服務器的日誌格式,,用於記錄首部信息需要查看的可以更改:
得到來自真實客戶端的IP:
option http-servrt-close:當選擇長了連接時啓用,服務器端主動把後端連接關閉,否則會長 時間佔據後端服務器端的連接;
option http-pretend-keepalive 假裝長連接。即,由於後端服務器不支持長連接,而客戶端與前端 HAproxy服務器端是長連接,若後端反饋給前端的是已斷開,則前端也會 斷開連接,此命令就是用於假裝後端還是連着。當前端發出請求時,後 端服務器可再次啓用。
haproxy的acl:
haproxy的ACL用於實現基於請求報文的首部、響應報文的內容或其它的環境狀態信息來做出轉發決策,這大大增強了其配置彈性。其配置法則通常分爲兩步,首先去定義ACL,即定義一個測試條件,而後在條件得到滿足時執行某特定的動作,如阻止請求或轉發至某特定的後端。定義ACL的語法格式如下。
acl <aclname> <criterion> [flags] [operator] <value> ...
<aclname>:ACL名稱,區分字符大小寫,且其只能包含大小寫字母、數字、-(連接線)、_(下劃線)、 .(點號)和:(冒號);haproxy中,acl可以重名,這可以把多個測試條件定義爲一個共同的acl;
<criterion>:測試標準,即對什麼信息發起測試;測試方式可以由[flags]指定的標誌進行調整;而有些測 試標準也可以需要爲其在<value>之前指定一個操作符[operator];
[flags]:目前haproxy的acl支持的標誌位有3個:
-i:不區分<value>中模式字符的大小寫;
-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 <integer>
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 <integer>
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是否以<string>指定的模式開頭。下面的例子用於測試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>指定的模式。例如,下面的例子用記測試請求是否爲提供靜態內容的主機img、video、download或ftp。
acl host_static hdr_beg(host) -i img. video. download. ftp.
5.1.8 hdr_end <string>
用於測試請求報文的指定首部的結尾部分是否符合<string>指定的模式。例如,下面的例子用記測試請求是否爲
動靜分離的示例:
frontend main
bind *:80
bind *:8080
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
use_backend static if url_static
default_backend appsrvs
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
balance roundrobin
server static1 172.16.100.11 check
server static2 172.16.100.12 check
backend appsrvs
balance roundrobin
option forwardfor except 127.0.0.1 header X-Client
option httpchk
cookie SERVERID insert indirect nocache
server web1 172.16.100.7:80 check cookie web1
server web2 172.16.100.8:80 check cookie web2