1. 程序環境:
- 程序:
/usr/sbin/haproxy
- 主配置文件:
/etc/haproxy/haproxy.cfg
- Unit file:
/usr/lib/systemd/system/haproxy.service
2. 配置段:
-
global:
全局配置段
進程及安全配置相關的參數
性能調整相關參數
Debug參數 -
proxies:
代理配置段
defaults:為frontend, listen, backend提供默認配置;
fronted:前端,相當于nginx, server {}
backend:后端,相當于nginx, upstream {}
listen:同時擁前端和后端
3. global配置參數:
為haproxy進程級別參數,且常與其運行的OS相關
大多數不需修改;haproxy進程相關的屬性定義,且多數與HAProxy所運行的OS相關;進程管理及安全相關的參數:
chroot:禁錮,修改haproxy的工作目錄至指定的目錄并在放棄權限之前執行chroot()操作,可以提升haproxy的安全級別,不過需要注意的是要確保指定的目錄為空目錄且任何用戶均不能有寫權限;
daemon:運行為守護進程;讓haproxy以守護進程的方式工作于后臺,其等同于-D選項的功能;當然,也可在命令行中以-db選項將其禁用;
user:同uid,但使用的是用戶名;
group:同gid,不過指定的是組名;
uid <number>:以指定的UID身份運行haproxy進程;
gid <number>:以指定的GID運行haproxy,建議使用專用于運行haproxy的GID,以免因權限問題帶來風險;
*log:定義全局的syslog服務器,最多可定義兩個,用于實現將haproxy產生的日志發往此服務器予以存儲;
log <address> <facility> [max level [min level]]
log-send-hostname [<string>]:在syslog信息的首部添加當前主機名,可以為string指定的名稱,也可省略使用當前主機名;
nbproc <number>:指明要啟動的haproxy進程的數量;默認1個;大于1個只能以守護進程啟動;通常不建議啟動多個;鑒于調試困難等多方面原因,一般只在單進程僅能打開少數文件描述符的場景中才使用多進程模式;
pidfile:
ulimit-n <number>:設定每個haproxy進程所能打開的最大文件(描述符)數量;應該大于maxconn值,haproxy自動動計算此數據為其設定合理值;不用調整;
stats:
node:定義當前節點的名稱,用于HA場景中多haproxy進程共享同一個IP地址時;
description:當前實例的描述信息;
4. 性能調整相關的參數:
*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>:在haproxy后端有著眾多服務器的場景中,在精確的時間間隔后統一對眾多服務器進行健康狀況檢查可能會帶來意外問題;此選項用于將其檢查的時間間隔長度上增加或減少一定的隨機時長;百分比,表示時間間隔的百分之幾;打散健康狀態檢測機制發出的時間,提前或延后,一般不大于檢測時間的50%;0表示不散開,到時間點就檢測;
tune.bufsize:設定buffer緩沖區大小;同樣的內存條件小,較小的值可以讓haproxy有能多的并發連接,較大的值可以讓某些應用程序使用較大的cookie信息;默認為16384,其可以在編譯時修改,不過強烈建議使用默認值;
tune.chksize:進程緩沖區大小;設定檢查緩沖區的大小,單位為字節,更大的值有助于在較大的頁面中完成基于字符串后模式的文本查找,但也會占用更大的系統資源;不建議修改;
tune.maxaccept:設定haproxy進程內核調度運行時一次性可以接受的連接的個數,較大的值可以帶來較大的吞吐率,默認在單進程模式下為100,多進程模式下為8,設定為-1可以禁止此限制;一般不建議修改;
tune.maxpollevents:設定一次系統調用可以處理的事件最大數,默認值取決于OS,其值小于200時,可節約帶寬,但會略微增大網絡延遲,而大于200時會降低延遲,但會稍稍增加網絡帶寬的占用量;
tune.maxrewrite:設定為首部重寫或追加而預留的緩存空間,建議使用1024左右的大小,在需要使用更大的空間時,haproxy會自動增加其值;
...tune.rcvbuf.client:面向客戶端的接收緩沖;
tune.sndbuf.client:面向客戶端的發送緩沖;
tune.rcvbuf.server:設定內核套接字中服務端或客戶端接收緩沖的大小,單位為字節;強烈建議使用默認值;面向服務器端的接收緩沖;
tune.sndbuf.server:面向服務器端的發送緩沖;
5. debug相關的參數:
- debug:詳細輸出信息;
- quiet:靜默模式;
簡單示例:
準備2各后端主機,并配置index.html
[root@backend1 ~]# vim /var/www/html/index.html
<h1>backend server 192.168.43.13</h1>
[root@backend2 ~]# vim /var/www/html/index.html
<h1>backend server 192.168.43.14</h1>
[root@haproxy ~]# yum -y install haproxy #安裝
[root@haproxy ~]# vim /etc/rsyslog.conf #配置日志服務器
$ModLoad imudp
$UDPServerRun 514
local2.* /var/log/haproxy.log
[root@haproxy ~]# touch /var/log/haproxy.log
[root@haproxy ~]# chown haproxy.haproxy /var/log/haproxy.log
[root@haproxy ~]# systemctl restart rsyslog.service
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg #修改配置文件,添加如下內容
frontend web
bind *:80
default_backend websrvs
backend websrvs
balance roundrobin
server srv1 192.168.43.13:80 check
server srv2 192.168.43.14:80 check
訪問測試:
[root@localhost ~]# for i in {1..10}; do curl http://192.168.43.11; done
<h1>backend server 192.168.43.14</h1>
<h1>backend server 192.168.43.13</h1>
<h1>backend server 192.168.43.14</h1>
<h1>backend server 192.168.43.13</h1>
<h1>backend server 192.168.43.14</h1>
<h1>backend server 192.168.43.13</h1>
<h1>backend server 192.168.43.14</h1>
<h1>backend server 192.168.43.13</h1>
<h1>backend server 192.168.43.14</h1>
<h1>backend server 192.168.43.13</h1>
6. proxies代理配置段參數
<1>. bind :Define one or several listening addresses and/or ports in a frontend.在前端定義一個或多個監聽地址和/或端口
bind [<address>]:<port_range> [, ...] [param*]
<address>:
支持ipv4地址,ipv6地址,unix socket地址,abns(abstract namespace抽象名稱空間)僅用于Linux系統;
<port_range>:
可以是一個端口,例如::80; 也可是一個端口范圍,例如:2000-2100;
<path>:
使用unix socket套接字文件;
[param*]:
參數;
<2>. balance:設定調度方法,用在default,listen,backend中;
balance <algorithm> [<arguments>]
balance url_param <param> [check_post [<max_wait>]]
-
指定基于url的參數做調度;
URL的語法格式: <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag> <scheme> 協議 <user>:<password>@<host>:<port> 要求認證,指定用戶名、密碼、主機名或ip、端口; <params> 分號隔開的是參數,傳遞給請求的參數; 例如: ftp://downloads.magedu.com/pub/gnu;type=d http://www.magedu.com/hammers;sale=false/index.html;graphics=true ?<query> 問號隔開的是查詢串,指定向數據庫發起查詢條件; http://www.joes-hardware.com/inventory-check.cgi?item=12731 查詢數據庫item為12731的項目,返回給inventory-check.cgi這個腳本,再由此腳本處理以后的結果返回給客戶端; #<frag> 片段,同一頁面上的不同段落錨定
<3>.server:定義后端主機的各服務器及其選項;
-
<name>:
服務器的內部名稱,僅在haproxy中使用;主要作用會出現在日志及警告信息中,可用來判斷故障服務器,如果設定了http-send-server-name,它還將被添加至發往此服務器的請求首部當中; -
<address>:
服務器的ip地址,支持使用主機名; -
[:[port]]:
端口映射;省略時,表示與bind的端口相同; -
[param*]:
可選參數;backup:
設定為備用服務器,相當于sorry server;僅在所有服務器均不可用時,才啟用;check:
對后端服務器做健康狀態檢測,無check時,表示假設后端主機始終可用,同時可使用輔助參數有很多;健康狀態檢測又三種:網絡層檢測、傳輸層檢測(端口在未必服務正常,精確度不高)、應用層檢測;addr:
通過此地址進行健康狀態檢測;port <port>
:通過此端口進行健康狀態檢測;inter <delay>
:連續兩次檢測之間的時間間隔,默認2000毫秒;每隔多長時間做一次健康檢測;fastinter <delay>
:如果不指明inter,為2秒鐘,downinter <delay>
:fall <count>
:連續多少次的失敗檢測將標記服務器檢測為dead;默認3次;rise <count>
:連續多少次的成功檢測將標記服務器為available;默認2次;httpchk:
基于http協議進行健康狀態檢測;是獨立的參數;
類似的還有"smtpchk", "mysql-check", "pgsql-check" and "ssl-hello-chk"分別用來定義7層檢測的;check-send-proxy
check-ssl:
與后端通信使用ssl協議時此行用到;ciphers <ciphers>
:指明加密方法;ca-file <cafile>
:表示haproxy與后端服務器通信時基于ssl方式,指明ca證書文件;cookie <value>
:為當前server指定cookie值,用于實現基于cookie會話的粘性;此值會在set cookie時發給客戶端;客戶端每次請求時就會附加這個cookie;haproxy每次收到請求后,都會檢查,進行比對,并且比對完成后,將請求發往比對成功的服務器上;
客戶端發來的請求報文中,如果帶有cookie,這個cookie信息會跟每一個后端服務器的cookie進行比對,如果比對成功就會把用戶請求,始終發往比對成功的這臺服務器上去;
在haproxy上為每一個后端主機,通過server定義時,為每一個后端主機定義一個唯一標識,這個唯一標識是插入的cookie信息,作用是,如果后端服務器響應用戶請求至客戶端時,這個響應報文中會set cookie,就是告訴客戶端下次再來訪問就使帶著這個cookie,這個set cookie信息中將會包含在haproxy上為這個服務器指明的cookie標記符,每一個服務器要使用不同的cookie標記符;
例如,第一個主機標記為server1,第二個服務器主機標記為server2等等,如果是服務器1響應的,set cookie時為,就把server1響應給客戶端了;于是,客戶端在瀏覽器中就有了cookie信息,而cookie的值一大堆字符串就包含了server1;所以,客戶端一旦有了cookie,每一次向haproxy請求,都會附帶此前被設定的cookie當中就包含server1;于是,當haproxy收到請求以后,通過分析發現,里面帶的cookie是server1,而后端主機都有cookie,比較找到哪臺服務器是server1,就直接發給該服務器;這個意義就叫會話的粘性;
粘性有兩種級別,一種是在ip地址上決定,來自于同一地址的始終發往同一后端主機,第二種就是來自于同一用戶的會話始終發往同一后端主機;調度粒度更精細到了cookie級別;disabled
:表示禁用,類似于varnish中標記為down狀態;id <value>
:為每個服務器設置一個持久ID,是基于id的會話粘性才會用到;force-tlsv10
:強制使用協議版本;maxconn <maxconn>
:當前服務器支持的最大并發連接數,超出此值的連接將被放置請求隊列中;maxqueue <maxqueue>
:當前服務器的隊列上限;minconn <minconn>
:如果設定了此參數,那么,最大值就成為動態的,可以根據后端服務器負載狀態動態調整;non-tlsv
:禁止使用協議的版本;observe <mode>
:用于通過觀察服務器端的流量來做健康狀態判斷;默認是禁用的,因為會帶來資源使用壓力;-
mode {tcp | http | health}
:- 定義haproxy的工作模式;
- tcp:基于layer4實現代理;可代理mysql, pgsql, ssh, ssl等協議;
- http:僅當代理的協議為http時使用;
- health:工作為健康狀態檢查的響應模式,當連接請求到達時回應“OK”后即斷開連接;
- 定義haproxy的工作模式;
-
on-error <mode>
:當判斷后端服務器連續出現error時要做的模式;
<mode>
:- fastinter:
- fail-check:檢測失敗;
- sudden-death:間歇性down;
- mark-down:標記為down;
on-marked-down <action>
:標記為down時,執行的動作;on-marked-up <action>
:標記為up時,執行的動作;redir <prefix>
:將發往此服務器的所有的GET和HEAD請求重定向至指定的地址;這個地址完全可以是haproxy代理沒有關系的另外的主機;發送302響應碼;
例如:server srv1 192.168.1.1:80 redir http://image1.mydomain.com checkweight <weight>
:服務器的權重;
<4>. stats:統計接口啟用相關的參數
-
·stats enable:啟用統計頁,基于默認的參數啟用stats page;
- status uri:/haproxy?stats
- status realm:"HAProxy Statistics"
- stats auth:no authentication
- stats scope:no restriction
stats auth <user>:<passwd>
:認證時的賬號和密碼,可使用多次stats realm <realm>
:啟用統計信息并設置身份驗證領域;使用字符串中有空格時,要用轉義符或加雙引號;stats uri <prefix>
:自定義stats page uristats refresh <delay>
:設定自動刷新時間;默認單位秒;stats show-desc [ <desc> ]
:設定顯示狀態頁的描述信息stats admin { if | unless } <cond>
:啟動stats page 中的管理功能-
stats show-legends
:在統計頁添加信息;可添加如下:- cap:capabilities(proxy)
- mode: one of tcp,http or health(proxy)
- id:SNMP ID(proxy, socket, server)
- IP:(socket, server)
- cookie:(socket, server)
-
stats hide-version
:在統計頁隱藏版本信息示例: listen stats bind *:9009 stats enable stats uri /haproxyadmin?stats stats realm haproxy\ statistics stats auth admin:pass stats show-desc This is admin area stats hide-version stats admin if TRUE
<5>. cookie:基于cookie進行會話保持;
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
-
<name>
:is the name of the cookie which will be monitored, modified or inserted in order to bring persistence.用于指明cookie中的某個名稱,這個名稱定義了那一段cookie信息是用來做會話粘性時被監控、修改、或者插入信息以實現持久性的; -
rewirte
:重寫;整個cookie信息將會被haproxy重寫,并在內部加上服務器id信息,當然,也有可能把某些信息依然放進去,只是把其中的某些項改了;相當于把insert和prefix結合使用; -
insert
:插入;在原有的cookie中插入; -
prefix
:添加前綴;把cookie信息插入在原有cookie信息的最左側; - 分別表示跟cache Control相關時,在什么場景下cookie有效:
- indirect:
- nocache:當使用insert操作時,當客戶端經由一個代理連接haproxy主機時,推薦使用此選項;用來操作對應的cache標記來判定對應信息是否能夠作為重寫標準;
- postonly
- preserve:服務器可以保留某個指定的cookie標記,以實現基于此信息的轉發;
- httponly
- secure:指示haproxy在insert時添加一個secure cookie標記;作用在于不允許后端服務器操作里面的cookie信息;
- domain <domain>:對應的cookie對應在哪個域上;
- maxidle <idle>
- maxlife <life>
官方示例:
cookie JSESSIONID prefix
cookie SRV insert indirect nocache
cookie SRV insert postonly indirect
cookie SRV insert indirect nocache maxidle 30m maxlife 8h
解釋:
1.名稱為SESSIONID,在原有的這個名稱之前,基于prefix方式,加上當前server的id;就是第一次調度時,調度哪個server上,把哪個server id給它插入到原有cookie數據之前;
2.表示插入的名稱為SRV,基于insert方式操作,同時定義了indirect和nocache,此種方式比較常見;
示例:
backend websrvs
cookie WEBSRV insert nocache indirect
設定的WEBSRV相當于一個變量,調度到哪臺服務器,就把哪臺的服務器的cookie值賦給WEBSRV;
server srv1 172.16.100.6:80 weight 2 check rise 1 fall 2 maxconn 3000 cookie srv1
server srv2 172.16.100.7:80 weight 1 check rise 1 fall 2 maxconn 3000 cookie srv2
<6>. option:
-
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
:把發往backend server的請求報文中添加“X-Forwarded-For”首部,其值為真正的客戶端主機地址;此功能自動實現; 對于后端主機每一次訪問日志信息中記錄的客戶端是代理服務器的ip地址,應該記錄真正的客戶端ip地址;[ except <network> ]
:請求報文來自此處指定的網絡時不予添加此首部-
[ header <name> ]
:使用自定義的首部名稱,而非“X-Forwarded-For“示例: [root@backend2 ~]# vim /etc/httpd/conf/httpd.conf #編輯后端backend2的配置文件,修改日志格式 LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined 瀏覽器訪問:http://192.168.43.11/index.html [root@backend2 ~]# tail -4 /var/log/httpd/access_log #查看后端主機日志的區別 192.168.43.11 - - [25/Sep/2018:11:19:16 -0400] "GET / HTTP/1.1" 200 38 "-" "Mozilla/5.0 (Wws NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari.36 Edge/17.17134" 192.168.43.100 - - [25/Sep/2018:11:19:56 -0400] "GET / HTTP/1.1" 200 38 "-" "Mozilla/5.0 (ows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safar7.36 Edge/17.17134"
option forceclose
;no option forceclose
:啟用或禁用活動連接,就是面向客戶端連接時,響應完客戶端后是否立即斷開;option httpclose
;no option httpclose
:啟用或禁用被動http連接關閉,就是服務端是否關閉連接; haproxy默認支持保持連接功能的,如果客戶端不發送請求連接也一直存在;option http-keep-alive
;no option http-keep-alive
:是否啟用保持連接功能;如果啟用http-keep-alive,要結合option http-server-close一同使用option http-server-close
;no option http-server-close
:在服務器端啟用或禁用HTTP連接關閉
<7>.error:
- `errorfile <code> <file>:返回一個自定義的錯誤頁,而不是haproxy生成的;
-
<code>
:is the HTTP status code. Currently, HAProxy is capable of generating codes 200, 400, 403, 408, 500, 502, 503, and 504. -
<file>
:designates a file containing the full HTTP response.
-
-
errorloc <code> <url>; errorloc302 <code> <url>
:
<8>.req相關
reqadd <string> [{if | unless} <cond>]
: Add a header at the end of the HTTP request;;-
rspadd <string> [{if | unless} <cond>]
: Add a header at the end of the HTTP responserspadd X-Via:\ HAPorxy
reqdel <search> [{if | unless} <cond>]
reqidel <search> [{if | unless} <cond>] (ignore case)
:
Delete all headers matching a regular expression in an HTTP request-
rspdel <search> [{if | unless} <cond>]
rspidel <search> [{if | unless} <cond>] (ignore case)
:
Delete all headers matching a regular expression in an HTTP responserspidel Server.*
<9>.log:日志系統
-
log global 調用全局日志
log <address> [len <length>] <facility> [<level> [<minlevel>]]
-
<address>:
依然是日志服務器的地址,同全局配置; -
<facility>:
依然是發往日志服務器指定的設施來記錄日志; -
<level> [<minlevel>]:
指明級別,記錄的日志范圍;
-
no log:不記錄日志;
注意:為每個實例啟用事件和流量日志,可用于所有區段(代理),每個實例最多指定兩個log目標;
用來指明前端代理的日志發往的路徑;無論是全局還是每個代理配置,其中最多可以使用2個日志存放位置,但是如果全局定義了2個,在代理中又使用了log global,則這個代理上就不能再定義日志存放位置了;log-format <string>
:日志格式-
capture cookie <name> len <length>
Capture and log a cookie in the request and in the response.記錄請求及響應報文的cookie于日志中;-
<name>:
cookie信息的開頭字符; -
<length>:
記錄cookie的長度,單位字節;
-
-
capture request header <name> len <length>
Capture and log the last occurrence of the specified request header.記錄請求報文中的指定的首部的值于日志中;capture request header X-Forwarded-For len 15
-
capture response header <name> len <length>
Capture and log the last occurrence of the specified response header.記錄響應給客戶端的響應報文中的指定的首部的值于日志中;capture response header Content-length len 9 capture response header Location len 15
<10>. 傳輸壓縮機制;
-
compression algo <algorithm> ...
:啟用http協議的壓縮機制,指明壓縮算法gzip,deflage
支持的algo:- identity:通常僅debug時使用
- gzip:使用glib庫,也支持zlib庫
- deflate:支持zlib庫,信息壓縮
-
compression type <mime type> ...
:指明壓縮的MIMI類型;通常僅壓縮文本類型的資源;例如,text/html,text/plain; -
compression offload
:卸載器;例如與客戶端之間傳輸可以壓縮,但與上游服務器不再壓縮,反之亦然,類似這種概念;
<11>. 對后端服務器做http協議的健康狀態檢測:
option httpchk option httpchk <uri> option httpchk <method> <uri> option httpchk <method> <uri> <version>
定義基于http協議的7曾健康狀態檢測機制;
http-check expect [!] <match> <pattern>
:讓HTTP健康檢查考慮響應內容或特定狀態碼。
<12>. 連接超時時長:
timeout client <timeout>
Set the maximum inactivity time on the client side. 默認單位是毫秒;timeout server <timeout>
Set the maximum inactivity time on the server side.timeout http-keep-alive <timeout>
持久連接的持久時長;timeout http-request <timeout>
Set the maximum allowed time to wait for a complete HTTP requesttimeout connect <timeout>
Set the maximum time to wait for a connection attempt to a server to succeed.timeout client-fin <timeout>
Set the inactivity timeout on the client side for half-closed connections.timeout server-fin <timeout>
Set the inactivity timeout on the server side for half-closed connections.
<13>.其他相關參數
use_backend <backend> [{if | unless} <condition>]
Switch to a specific backend if/unless an ACL-based condition is matched.
當符合指定的條件時使用特定的backend;-
block { if | unless } <condition>
Block a layer 7 request if/unless a condition is matchedacl invalid_src src 172.16.200.2 block if invalid_src errorfile 403 /etc/fstab
http-request { allow | deny } [ { if | unless } <condition> ]
Access control for Layer 7 requeststcp-request connection {accept|reject} [{if | unless} <condition>]
Perform an action on an incoming connection depending on a layer 4 condition
7. acl:Access Control Lists
The use of Access Control Lists (ACL) provides a flexible solution to perform content switching and generally to take decisions based on content extracted from the request, the response or any environmental status.他使用訪問控制列表(ACL)提供了一個靈活的解決方案來執行內容切換,通常根據從請求、響應或任何環境狀態中提取的內容做出決策.
acl <aclname> <criterion> [flags] [operator] [<value>] ...
-
<aclname>:
指定acl名稱,可以使用大小寫字母、短橫線、下劃線、點號、冒號;區分字符大小寫。 -
<criterion>:
匹配標準,可以基于分析請求報文中的任何屬性信息,來作為判斷一次請求報文是否符合此處所定義acl;標準非常多,如請求報文原地址、請求報文的首部各信息等; -
[flags]
: 標志位;可以用以下標志位做值匹配時,基于什么標準來控制-
-i
: ignore case during matching of all subsequent patterns.在匹配所有后續模式時忽略大小寫;比較時使用。 -
-m
: use a specific pattern matching method;指定使用特定的模式匹配方式; -
-n
: forbid the DNS resolutions;禁止DNS解析; -
-u
: force the unique id of the ACL;強制acl的唯一id -
--
: force end of flags. Useful when a string looks like one of the flags. 強制結束標志。當字符串看起來像某個標志時非常有用
-
-
[operator] :
匹配后的操作符;- 做布爾型匹配:其值0表示false,1表示true;
- 做整型匹配:可用操作符為:
- eq:等于
- ge:大于等于
- gt:大于
- le:小于
- lt:小于等于
- 做字符串匹配:
- -m str:精確匹配;
- -m sub:做字串匹配;
- -m beg:匹配前綴,即開頭的字符串;
- -m end:匹配后綴;
- -m dir:匹配子路徑;
- -m dom:域名匹配;
- acl作為條件時的邏輯關系:
- 與(AND): 隱式條件
- 或(OR):explicit with the "or" keyword or the "||" operator
- 非:Negation with the exclamation mark ("!")
-
<value>
:值;- boolean:指定true或false;
- integer or integer range:指定整數或范圍;
- IP address / network:指定地址或地址范圍;
- string (exact, substring, suffix, prefix, subdir, domain):指定精確字符串、子串、前綴、后綴、...
- regular expression:指定正則表達式模式;
- hex block
- 注意:兩個acl的名稱可以一樣,二者合并起來作為一個條件;是或關系,即同名的acl的條件,滿足第一個或滿足第二個,表示都是能被匹配到;
criterion
常見的匹配標準
- 四層獲取匹配條件:
- dst IP:目標地址匹配;
- dst_port PORT:目標端口匹配;
- src IP:源地址匹配;
- src_port POST:源端口匹配;
- dst_conn : integer:目標連接數量匹配;
- 七層獲取匹配條件:
- path : string;這將提取請求的URL路徑,該路徑從第一個斜杠開始,在問號前面結束(不包含主機部分);即表示匹配檢查用戶請求的path路徑。
- path : exact string match;精確匹配某個url路徑
- path_beg : prefix match;匹配某個url路徑的前綴
- path_dir : subdir match;匹配某個url路徑的子路徑
- path_dom : domain match 匹配某個url路徑的域名
- path_end : suffix match 匹配某個url路徑的后綴
- path_len : length match 匹配某個url路徑的長度
- path_reg : regex match 匹配某個url路徑的正則表達式
- path_sub : substring match 匹配某個url路徑的子串
- url : string;表示匹配檢查用戶請求的url。一個典型的用法是使用具有預取功能的緩存,以及需要從數據庫聚合多個信息并將其保存在緩存中的門戶。
- url : exact string match
- url_beg : prefix match
- url_dir : subdir match
- url_dom : domain match
- url_end : suffix match
- url_len : length match
- url_reg : regex match
- url_sub : substring match
-
req.hdr([<name>[,<occ>]]) :
string; 這將在HTTP請求中提取報頭<name>
的最后一次出現。-
hdr([<name>[,<occ>]])
: exact string match -
hdr_beg([<name>[,<occ>]])
: prefix match;匹配指定報文首部的值以給定的字符開頭 -
hdr_dir([<name>[,<occ>]])
: subdir match;匹配指定報文首部的值以給定的子路徑 -
hdr_dom([<name>[,<occ>]])
: domain match;匹配指定報文首部的值以給定的域名 -
hdr_end([<name>[,<occ>]])
: suffix match;匹配指定報文首部的值以給定的后綴 -
hdr_len([<name>[,<occ>]])
: length match;匹配指定報文首部的值以給定的長度 -
hdr_reg([<name>[,<occ>]])
: regex match;匹配指定報文首部的值以給定的正則式 -
hdr_sub([<name>[,<occ>]])
: substring match 匹配指定報文首部的值以給定的子串
-
-
req.cook([<name>]) :
string:匹配請求報文中cookie的名字是否符合給定的值;-
cook([<name>]):
做精確cookie名稱匹配 -
cook_beg([<name>]):
做cookie的前綴匹配 -
cook_dir([<name>]):
做cookie的子路徑匹配 -
cook_dom([<name>]):
做cookie的域名匹配 -
cook_end([<name>]):
做cookie的后綴匹配 -
cook_len([<name>]):
做cookie的長度匹配 -
cook_reg([<name>]):
做cookie的正則式匹配 -
cook_sub([<name>]):
做cookie的子串匹配
-
- path : string;這將提取請求的URL路徑,該路徑從第一個斜杠開始,在問號前面結束(不包含主機部分);即表示匹配檢查用戶請求的path路徑。
-
Pre-defined ACLs:內建的acl變量
ACL name Equivalent to Usage FALSE always_false never match HTTP req_proto_http match if protocol is valid HTTP HTTP_1.0 req_ver 1.0 match HTTP version 1.0 HTTP_1.1 req_ver 1.1 match HTTP version 1.1 HTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length HTTP_URL_ABS url_reg ^[^/:]*:// match absolute URL with scheme HTTP_URL_SLASH url_beg / match URL beginning with "/" HTTP_URL_STAR url * match URL equal to "*" LOCALHOST src 127.0.0.1/8 match connection from local host METH_CONNECT method CONNECT match HTTP CONNECT method METH_GET method GET HEAD match HTTP GET or HEAD method METH_HEAD method HEAD match HTTP HEAD method METH_OPTIONS method OPTIONS match HTTP OPTIONS method METH_POST method POST match HTTP POST method METH_TRACE method TRACE match HTTP TRACE method RDP_COOKIE req_rdp_cookie_cnt gt 0 match presence of an RDP cookie REQ_CONTENT req_len gt 0 match data in the request buffer TRUE always_true always match WAIT_END wait_end wait for end of content analysis
8. 基于acl實現智能負載均衡
準備兩個靜態虛擬主機:
[root@websrvs ~]# cd /etc/httpd/conf.d/
[root@websrvs conf.d]# vim vhost1.conf
<VirtualHost *:80>
ServerName www.ilinux.io
DocumentRoot "/data/web/host1"
<Directory "/data/web/host1">
Options None
AllowOverride None
require all granted
</Directory>
</VirtualHost>
Listen 8080
<VirtualHost *:8080>
ServerName www.inux.io
DocumentRoot "/data/web/host2"
<Directory "/data/web/host2">
Options None
AllowOverride None
require all granted
</Directory>
</VirtualHost>
給兩個虛擬主機準備2個主頁文件index.html:
[root@websrvs conf.d]# mkdir /data/web/host{1,2}
[root@websrvs ~]# vim /data/web/host1/index.html
<h1>www.ilinux.io</h1>
[root@websrvs ~]# vim /data/web/host2/index.html
<h1>www.inux.io</h1>
準備兩個動態虛擬主機:
[root@phpsrvs conf.d]# vim vhost1.conf
<VirtualHost *:80>
ServerName www.ilinux.com
DocumentRoot "/data/web/host1"
<Directory "/data/web/host1">
Options None
AllowOverride None
require all granted
</Directory>
</VirtualHost>
Listen 8080
<VirtualHost *:8080>
ServerName www.inux.com
DocumentRoot "/data/web/host2"
<Directory "/data/web/host2">
Options None
AllowOverride None
require all granted
</Directory>
</VirtualHost>
[root@phpsrvs ~]# yum -y install php
準備2各動態主頁index.php
[root@phpsrvs ~]# vim /data/web/host1/index.php
<h1>www.ilinux.com</h1>
<?php
phpinfo();
?>
[root@phpsrvs ~]# vim /data/web/host2/index.php
<h1>www.inux.com</h1>
<?php
phpinfo();
?>
[root@phpsrvs ~]# systemctl start httpd.service
安裝配置haproxy:
[root@haproxy ~]# yum -y install haproxy
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend https
bind *:80
# bind *:443 ssl crt /etc/haproxy/certs/haproxy.pem #實現基于ssl的會話
# redirect scheme https if !{ ssl_fc }
acl php_page path_end -i .php
use_backend phpsrvs if php_page
default_backend websrvs
backend websrvs
balance roundrobin
server srv1 192.168.43.14:80 check
server srv2 192.168.43.14:8080 check
backend phpsrvs
balance roundrobin
# cookie php insert indirect nocache
server srv1 192.168.43.13:80 check cookie ph1
server srv2 192.168.43.13:8080 check cookie ph2
listen stats
bind *:9009
stats enable
stats uri /haproxyadmin?stats
stats realm haproxy\ statistics
stats auth admin:pass
stats show-desc This is admin area
stats hide-version
stats admin if TRUE
[root@haproxy ~]# systemctl start haproxy.service
#使用curl訪問靜態服務器測試:
[root@haproxy ~]# for i in {1..10};do curl http://192.168.43.11; done;
<h1>www.inux.io</h1>
<h1>www.ilinux.io</h1>
<h1>www.inux.io</h1>
<h1>www.ilinux.io</h1>
<h1>www.inux.io</h1>
<h1>www.ilinux.io</h1>
<h1>www.inux.io</h1>
<h1>www.ilinux.io</h1>
<h1>www.inux.io</h1>
<h1>www.ilinux.io</h1>
使用瀏覽器訪問測試: