負載均衡之HAProxy——種種

HAProxy原理和配置

1.HAProxy簡介

(1)HAProxy 是一款提供高可用性、負載均衡以及基於TCP(第四層)和HTTP(第七層)應用的代理軟件,支持虛擬主機,它是免費、快速而且可靠的          一種解決方案。 HAProxy特別適用於那些負載特大的web站點,這些站點一般又須要會話保持或七層處理。HAProxy運行在時下的硬件上,徹底              能夠支持數以萬計的 併發鏈接。而且它的運行模式使得它能夠很簡單安全的整合進您當前的架構中, 同時能夠保護你的web服務器不被暴露到網            絡上。javascript

(2)HAProxy 實現了一種事件驅動、單一進程模型,此模型支持很是大的併發鏈接數。多進程或多線程模型受內存限制 、系統調度器限制以及無處不在          的鎖限制,不多能處理數千併發鏈接。事件驅動模型由於在有更好的資源和時間管理的用戶端(User-Space) 實現全部這些任務,因此沒有這些問              題。此模型的弊端是,在多核系統上,這些程序一般擴展性較差。這就是爲何他們必須進行優化以 使每一個CPU時間片(Cycle)作更多的工做。css

(3)HAProxy 支持鏈接拒絕 : 由於維護一個鏈接的打開的開銷是很低的,有時咱們很須要限制攻擊蠕蟲(attack bots),也就是說限制它們的鏈接打開          從而限制它們的危害。 這個已經爲一個陷於小型DDoS攻擊的網站開發了並且已經拯救了不少站點,這個優勢也是其它負載均衡器沒有的。html

(4)HAProxy 支持全透明代理(已具有硬件防火牆的典型特色): 能夠用客戶端IP地址或者任何其餘地址來鏈接後端服務器. 這個特性僅在Linux 2.4/2.6          內核打了cttproxy補丁後纔可使用. 這個特性也使得爲某特殊服務器處理部分流量同時又不修改服務器的地址成爲可能。前端

 

性能java

HAProxy藉助於OS上幾種常見的技術來實現性能的最大化。python

1,單進程、事件驅動模型顯著下降了上下文切換的開銷及內存佔用。mysql

2,O(1)事件檢查器(event checker)容許其在高併發鏈接中對任何鏈接的任何事件實現即時探測。linux

3,在任何可用的狀況下,單緩衝(single buffering)機制能以不復制任何數據的方式完成讀寫操做,這會節約大量的CPU時鐘週期及內存帶寬;nginx

4,藉助於Linux 2.6 (>= 2.6.27.19)上的splice()系統調用,HAProxy能夠實現零複製轉發(Zero-copy forwarding),在Linux 3.5及以上的OS中還能夠實      現零複製啓動(zero-starting);git

5,內存分配器在固定大小的內存池中可實現即時內存分配,這可以顯著減小建立一個會話的時長;

6,樹型存儲:側重於使用做者多年前開發的彈性二叉樹,實現了以O(log(N))的低開銷來保持計時器命令、保持運行隊列命令及管理輪詢及最少鏈接隊           列;

7,優化的HTTP首部分析:優化的首部分析功能避免了在HTTP首部分析過程當中重讀任何內存區域;

8,精心地下降了昂貴的系統調用,大部分工做都在用戶空間完成,如時間讀取、緩衝聚合及文件描述符的啓用和禁用等;

全部的這些細微之處的優化實現了在中等規模負載之上依然有着至關低的CPU負載,甚至於在很是高的負載場景中,5%的用戶空間佔用率和95%的系統空間佔用率也是很是廣泛的現象,這意味着HAProxy進程消耗比系統空間消耗低20倍以上。所以,對OS進行性能調優是很是重要的。即便用戶空間的佔用率提升一倍,其CPU佔用率也僅爲10%,這也解釋了爲什麼7層處理對性能影響有限這一現象。由此,在高端系統上HAProxy的7層性能可輕易超過硬件負載均衡設備。

在生產環境中,在7層處理上使用HAProxy做爲昂貴的高端硬件負載均衡設備故障故障時的緊急解決方案也時長可見。硬件負載均衡設備在「報文」級別處理請求,這在支持跨報文請求(request across multiple packets)有着較高的難度,而且它們不緩衝任何數據,所以有着較長的響應時間。對應地,軟件負載均衡設備使用TCP緩衝,可創建極長的請求,且有着較大的響應時間。

HAProxy目前主要有三個版本: 1.3 , 1.4 ,1.5,CentOS6.6 自帶的RPM包爲 1.5 的。

LB Cluster:
四層:
lvs, nginx(stream),haproxy(mode tcp)
七層:
http: nginx(http, ngx_http_upstream_module), haproxy(mode http), httpd, ats, perlbal, pound…

實現原理

四層代理: 經過分析IP層及TCP/UDP層的流量實現的基於「IP+端口」的負載均衡。

七層: 能夠根據內容,再配合負載均衡算法來選擇後端服務器,不但能夠根據 「ip+端口」方式進行負載分流,還能夠根據網站的URL,訪問域名,瀏覽 器類別,語言等決定負載均衡的策略。

七層負載均衡模式下,負載均衡與客戶端及後端的服務器會分別創建一次 TCP鏈接,而在四層負載均衡模式下(DR),僅創建一次TCP鏈接;七層負載均衡對負載均衡設備的要求更高,處理能力也低於四層負載均衡。

Haproxy的特性:

  • 一、可靠性與穩定性都很是出色,可與硬件級設備媲美。
  • 二、支持鏈接拒絕,能夠用於防止DDoS攻擊
  • 三、支持長鏈接、短鏈接和日誌功能,可根據須要靈活配置
  • 四、路由HTTP請求到後端服務器,基於cookie做會話綁定;同時支持經過獲取指定 的url來檢測後端服務器的狀態
  • 五、HAProxy還擁有功能強大的ACL支持,可靈活配置路由功能,實現動靜分離,在架構設計與實現上帶來很大方便
  • 六、可支持四層和七層負載均衡,幾乎能爲全部服務常見的提供負載均衡功能
  • 七、擁有功能強大的後端服務器的狀態監控web頁面,能夠實時瞭解設備的運行狀態 ,還可實現設備上下線等簡單操做。
  • 八、支持多種負載均衡調度算法,而且也支持session保持。

HAProxy:
http://www.haproxy.org
http://www.haproxy.com

文檔:
http://cbonte.github.io/haproxy-dconv/

HAProxy is a TCP/HTTP reverse proxy which is particularly suited for high availability environments. Indeed, it can:
: – route HTTP requests depending on statically assigned cookies
: – spread load among several servers while assuring server persistence
: through the use of HTTP cookies
: – switch to backup servers in the event a main server fails
: – accept connections to special ports dedicated to service monitoring
: – stop accepting connections without breaking existing ones
: – add, modify, and delete HTTP headers in both directions
: – block requests matching particular patterns
: – report detailed status to authenticated users from a URI intercepted by the application

HAProxy是一種TCP/HTTP反向代理,特別適合於高可用性環境。事實上,它能夠:

: -根據靜態分配的cookie路由HTTP請求

: -在多個服務器之間擴展負載,同時保證服務器的持久性

: -經過使用HTTP cookie。

: -當主服務器發生故障時,切換到備份服務器

: -接受專用於服務監控的專用端口的鏈接

: -中止接受鏈接而不破壞現有的鏈接

: -添加、修改和刪除兩個方向的HTTP頭

: -塊請求匹配特定的模式。

: -從被應用程序截獲的URI中向通過身份驗證的用戶報告詳細狀態。

版本:1.4, 1.5, 1.6, 1.7

程序環境:
主程序:/usr/sbin/haproxy
主配置文件:/etc/haproxy/haproxy.cfg
Unit file:/usr/lib/systemd/system/haproxy.service

配置段:
global:全局配置段
進程及安全配置相關的參數
性能調整相關參數
Debug參數
用戶列表
peers
proxies:代理配置段
defaults:爲frontend, listen, backend提供默認配置;
fronted:前端,至關於nginx, server {}
backend:後端,至關於nginx, upstream {}
listen:同時擁前端和後端

2.haproxy安裝和配置說明

haproxy的安裝,CentOS7.4 自帶的RPM包爲 1.5 的

yum install haproxy -y

haproxy的默認配置文件

[root@HAProxy ~]# cat /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Example configuration for a possible web application.  See the
# full configuration options online.
#
#   http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
#
#---------------------------------------------------------------------

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global                                                                #全局配置文件
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2        #日誌配置,全部的日誌都記錄本地,經過local2輸出
  
    chroot      /var/lib/haproxy        #修改haproxy的工做目錄至指定的目錄並在放棄權限以前執行chroot()操做,能夠提高haproxy的安全級別,不過須要注意的是要確保指定的目錄爲空目錄且任何用戶均不能有寫權限;
    pidfile     /var/run/haproxy.pid    #指定pid文件的路徑
    maxconn     4000                    #最大鏈接數的設定
    user        haproxy                 #指定運行服務的用戶
    group       haproxy                 #指定運行服務的用戶組
    daemon

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http     #默認使用協議,能夠爲{http|tcp|health} http:是七層協議 tcp:是四層   health:只返回OK
    log                     global   #全局日誌記錄
    option                  httplog     #詳細記錄http日誌
    option                  dontlognull  #不記錄空日誌
    option http-server-close             #啓用http-server-close
    option forwardfor       except 127.0.0.0/8  #來自這些信息的都不forwardfor
    option                  redispatch  #從新分發,ServerID對應的服務器宕機後,強制定向到其餘運行正常的服務器
    retries                 3     #3次鏈接失敗則認爲服務不可用
    timeout http-request    10s   #默認http請求超時時間
    timeout queue           1m    #默認隊列超時時間
    timeout connect         10s   #默認鏈接超時時間
    timeout client          1m    #默認客戶端超時時間
    timeout server          1m     #默認服務器超時時間
    timeout http-keep-alive 10s    #默認持久鏈接超時時間
    timeout check           10s    #默認檢查時間間隔
    maxconn                 3000   #最大鏈接數

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  main *:5000
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js
      #定義ACL規則以如".html"結尾的文件;-i:忽略大小寫
    use_backend static          if url_static  #調用後端服務器並檢查ACL規則是否被匹配
    default_backend             app            #客戶端訪問時默認調用後端服務器地址池

#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static                                   #定義後端服務器
    balance     roundrobin                       #定義算法;基於權重進行輪詢
    server      static 127.0.0.1:4331 check      #check:啓動對後端server的健康狀態檢測

   
#---------------------------------------------------------------------
# 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

 

 

 

 

IaaS, PaaS, SaaS
LBaaS, DBaaS, FWaaS, FaaS(Serverless), …
OpenShift(PaaS): HAPorxy, Ingress Controller

 

如下爲配置的詳細說明

global配置參數:
進程及安全管理:chroot, daemon,user, group, uid, gid
log:定義全局的syslog服務器;最多能夠定義兩個;
log <address> [len <length>] <facility> [max level [min level]]
nbproc <number>:要啓動的haproxy的進程數量;
ulimit-n <number>:每一個haproxy進程可打開的最大文件數;

性能調整:
maxconn <number>:設定每一個haproxy進程所能接受的最大併發鏈接數;Sets the maximum per-process number of concurrent                                                                  connections to <number>.
整體的併發鏈接數:nbproc * maxconn
maxconnrate <number>:Sets the maximum per-process number of connections per second to <number>. 每一個進程每秒種所能建立的最大鏈接數量;
maxsessrate <number>:
maxsslconn <number>: Sets the maximum per-process number of concurrent SSL connections to <number>.
設定每一個haproxy進程所能接受的ssl的最大併發鏈接數;
spread-checks <0..50, in percent>

proxies配置參數

代理配置段:
– defaults <name>
– frontend <name>
– backend <name>
– listen <name>

Frontend段:指定接收客戶端鏈接偵聽套接字設置
Backend段:指定將鏈接請求轉發至後端服務器的相關設置
Listen段:指定完整的先後端設置,只對 TCP 有效
proxy 名稱:使用字母 數字 – _ . : 並區分字符大小寫

 

bind配置

配置參數:

bind: 指定一個或多個前端偵聽地址和端口只用於frountend配置段和listen配置段
bind [<address>]:<port_range> [, …] [param*]

listen http_proxy
         bind :80,:443
         bind 10.0.0.1:10080,10.0.0.1:10443
         bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy​

Balance配置

balance:後端服務器組內的服務器調度算法
balance <algorithm> [ <arguments> ]
balance url_param <param> [check_post]

haproxy中調度算法一樣分爲動態調度算法和靜態調度算法,與nginx調度算法中區分動靜態調度算法的概念不一樣,nginx用能不能根據後端服務器的負載情況進行調度來區分動靜態調度算法的差異,而haproxy中則根據該算法支不支持運行時即時生效來區分動靜態算法

算法:
roundrobin:Each server is used in turns, according to their weights.
server options: weight #  動態算法:支持權重的運行時調整,支持慢啓動;每一個後端中最多支持4095個server;
static-rr:  靜態算法:不支持權重的運行時調整及慢啓動;後端主機數量無上限;
leastconn:推薦使用在具備較長會話的場景中,例如MySQL、LDAP等;
first:根據服務器在列表中的位置,自上而下進行調度;前面服務器的鏈接數達到上限,新請求才會分配給下一臺服務;
source:源地址hash;
除權取餘法:
一致性哈希:
uri:對URI的左半部分作hash計算,並由服務器總權重相除之後派發至某挑出的服務器;

 

動靜態取決於hash type

hash-type
    map-based
    consistent​

 

 

URL的組成
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

 

schame:方案,訪問服務器以獲取資源時要使用哪一種協議 
user:用戶,某些方案訪問資源時須要的用戶名 
password:密碼,用戶對應的密碼,中間用:分隔 
host:主機,資源宿主服務器的主機名或IP地址 
port:端口,資源宿主服務器正在監聽的端口號,不少方案有默認端口號 
path:路徑,服務器資源的本地名,由一個/將其與前面的URL組件分隔 
params:參數,指定輸入的參數,參數爲名/值對,多個參數,用;分隔 
query:查詢,傳遞參數給程序,如數據庫,用?分隔,多個查詢用&分隔 
frag:片斷,一小片或一部分資源的名字,此組件在客戶端使用,用#分隔

 

左半部分:/<path>;<params>
整個uri:/<path>;<params>?<query>#<frag>

username=jerry

url_param:對用戶請求的uri的<params>部分中的參數的值做hash計算,並由服務器總權重相除之後派發至某挑出的服務器;一般用於追蹤用戶,以                          確保來自同一個用戶的請求始終發往同一個Backend Server;

hdr(<name>):對於每一個http請求,此處由<name>指定的http首部將會被取出作hash計算; 並由服務器總權重相除之後派發至某挑出的服務器;沒                                有有效值的會被輪詢調度;
hdr(Cookie)

rdp-cookie
rdp-cookie(<name>)

hash-type:哈希算法
hash-type <method> <function> <modifier>
map-based:除權取餘法,哈希數據結構是靜態的數組;
consistent:一致性哈希,哈希數據結構是一個樹;

<function> is the hash function to be used : 哈希函數
sdbm
djb2
wt6

default_backend <backend>
設定默認的backend,用於frontend中;

default-server [param*]
爲backend中的各server設定默認選項;

server <name> <address>[:[port]] [param*]
定義後端主機的各服務器及其選項;

server <name> <address>[:port] [settings …]
default-server [settings …]

<name>:服務器在haproxy上的內部名稱;出如今日誌及警告信息中;
<address>:服務器地址,支持使用主機名;
[:[port]]:端口映射;省略時,表示同bind中綁定的端口;
[param*]:參數
maxconn <maxconn>:當前server的最大併發鏈接數;
backlog <backlog>:當前server的鏈接數達到上限後的後援隊列長度;
backup:設定當前server爲備用服務器;
check:對當前server作健康狀態檢測;
addr :檢測時使用的IP地址;
port :針對此端口進行檢測;
inter <delay>:連續兩次檢測之間的時間間隔,默認爲2000ms;
rise <count>:連續多少次檢測結果爲「成功」才標記服務器爲可用;默認爲2;
fall <count>:連續多少次檢測結果爲「失敗」才標記服務器爲不可用;默認爲3;

注意:option httpchk,」smtpchk」, 「mysql-check」, 「pgsql-check」 and 「ssl-hello-chk」 用於定義應用層檢測方法;

 

基於cookie的會話綁定

cookie <value>:爲當前server指定其cookie值,用於實現基於cookie的會話黏性;
disabled:標記爲不可用;
on-error <mode>:後端服務故障時的行動策略;
– fastinter: force fastinter
– fail-check: simulate a failed check, also forces fastinter (default)
– sudden-death: simulate a pre-fatal failed health check, one more failedcheck will mark a server down, forces fastinter
– mark-down: mark the server immediately down and force fastinter
redir <prefix>:將發往此server的全部GET和HEAD類的請求重定向至指定的URL;
weight <weight>:權重,默認爲1;

OK –> PROBLEM
OK –> PROBLEM –> PROBLEM –> PROBLEM
PROBLEM –> OK

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.
rewirte:重寫;
insert:插入;
prefix:前綴;

基於cookie的session sticky的實現:

backend websrvs
cookie WEBSRV insert nocache indirect
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 ​

統計接口啓用相關的參數

stats enable
啓用統計頁;基於默認的參數啓用stats page;
– stats uri : /haproxy?stats
– stats realm : 「HAProxy Statistics」
– stats auth : no authentication
– stats scope : no restriction

stats auth <user>:<passwd>           認證時的帳號和密碼,可以使用屢次;
stats realm <realm>                         認證時的realm;
stats uri <prefix>                               自定義stats page uri
stats refresh <delay>                        設定自動刷新時間間隔;
stats admin { if | unless } <cond>     啓用stats page中的管理功能

配置示例:

listen stats
    bind :9099
    stats enable
    stats realm HAPorxy\ Stats\ Page
    stats auth admin:admin
    stats admin if TRUE ​

maxconn <conns>:爲指定的frontend定義其最大併發鏈接數;默認爲2000;
Fix the maximum number of concurrent connections on a frontend.

 

haproxy的工做模式

mode { tcp|http|health }   定義haproxy的工做模式;
tcp:基於layer4實現代理;可代理mysql, pgsql, ssh, ssl等協議;
http:僅當代理的協議爲http時使用;
health:工做爲健康狀態檢查的響應模式,當鏈接請求到達時迴應「OK」後即斷開鏈接;

示例:

listen ssh
bind :22022
balance leastconn
mode tcp
server sshsrv1 172.16.100.6:22 check
server sshsrv2 172.16.100.7:22 check ​

 

forwardfor配置

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
Enable insertion of the X-Forwarded-For header to requests sent to servers
在由haproxy發日後端主機的請求報文中添加「X-Forwarded-For」首部,其值前端客戶端的地址;用於向後端主發送真實的客戶端IP;

 

[ except <network> ]:請求報請來自此處指定的網絡時不予添加此首部;
[ header <name> ]:使用自定義的首部名稱,而非「X-Forwarded-For」;

[ if-none ] 若是沒有首部才添加首部,若是有使用默認值

爲指定的MIME類型啓用壓縮傳輸功能
compression algo <algorithm> …:啓用http協議的壓縮機制,指明壓縮算法gzip, deflate
compression type <mime type> …:指明壓縮的MIMI類型

 

錯誤頁配置

errorfile <code> <file>
Return a file contents instead of errors generated by 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.

示例:

errorfile 400 /etc/haproxy/errorfiles/400badreq.http
errorfile 408 /dev/null # workaround Chrome pre-connect bug
errorfile 403 /etc/haproxy/errorfiles/403forbid.http
errorfile 503 /etc/haproxy/errorfiles/503sorry.http

errorloc <code> <url>
errorloc302 <code> <url>

errorfile 403 http://www.magedu.com/error_pages/403.html

 

修改報文首部

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 response
在響應報文尾部添加指定首部

示例

rspadd 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 response
不分大小寫從響應報文中刪除匹配正則表達式的首部

示例

rspidel Server.*​

會話保持

haproxy負載均衡保持客戶端和服務器Session的三種方式:

1 用戶源IP 識別

haroxy 將用戶IP通過hash計算後 指定到固定的真實服務器上(相似於nginx 的IP hash 指令)

配置指令 balance source

backend www

mode http

balance source

server web1  192.168.0.150:80 check inter 1500 rise 3 fall 3

server web2  192.168.0.151:80 check inter 1500 rise 3 fall 3

 

2 cookie 識別

haproxy 將WEB服務端發送給客戶端的cookie中插入(或添加加前綴)haproxy定義的後端的服務器COOKIE ID。

配置指令例舉 cookie SESSION_COOKIE insert indirect nocache

用firebug能夠觀察到用戶的請求頭的cookie裏 有相似」 Cookie jsessionid=0bc588656ca05ecf7588c65f9be214f5;

SESSION_COOKIE=app1″

SESSION_COOKIE=app1就是haproxy添加的內容。

 

backend COOKIE_srv

mode http

cookie SESSION_COOKIE insert indirect nocache

server web1 192.168.0.150:80  cookie 1 check inter 1500 rise 3 fall 3

server web2 192.168.0.151:80  cookie 2 check inter 1500 rise 3 fall 3

 

3 session 識別

haproxy 將後端服務器產生的session和後端服務器標識存在haproxy中的一張表裏。客戶端請求時先查詢這張表。

配置指令:appsession <cookie> len <length> timeout <holdtime>

配置指令例舉 appsession JSESSIONID len 64 timeout 5h request-learn

配置舉例

backend APPSESSION_srv

mode http

appsession JSESSIONID len 64 timeout 5h request-learn

server web1 192.168.0.150:80 cookie 1 check inter 1500 rise 3 fall 3

server web2 192.168.0.151:80 cookie 2 check inter 1500 rise 3 fall 3

日誌系統

log:
log global
log <address> [len <length>] <facility> [<level> [<minlevel>]]
no log

注意:
默認發往本機的日誌服務器;
(1) local2.* /var/log/local2.log
(2) $ModLoad imudp
$UDPServerRun 514

log-format <string>:
課外實踐:參考文檔實現combined格式的記錄

capture cookie <name> len <length>
Capture and log a cookie in the request and in the response.

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

爲指定的MIME類型啓用壓縮傳輸功能
compression algo <algorithm> …:啓用http協議的壓縮機制,指明壓縮算法gzip, deflate;
compression type <mime type> …:指明壓縮的MIME類型;常適用於壓縮的類型爲文本類型;

對後端服務器作http協議的健康狀態檢測:
option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>
定義基於http協議的7層健康狀態檢測機制;

http-check expect [!] <match> <pattern>
Make HTTP health checks consider response contents or specific status codes.

鏈接超時時長:
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 request

timeout 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.

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 matched

acl 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 requests

tcp-request connection {accept|reject} [{if | unless} <condition>]
Perform an action on an incoming connection depending on a layer 4 condition

示例:
listen ssh
bind :22022
balance leastconn
acl invalid_src src 172.16.200.2
tcp-request connection reject if invalid_src
mode tcp
server sshsrv1 172.16.100.6:22 check
server sshsrv2 172.16.100.7:22 check backup

 

acl

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 <aclname> <criterion> [flags] [operator] [<value>] …
<aclname>:ACL names must be formed from upper and lower case letters, digits, ‘-‘ (dash), ‘_’ (underscore) , ‘.’ (dot) and ‘:’ (colon).ACL                                 names are case-sensitive.
<value>的類型:
– boolean
– integer or integer range
– IP address / network
– string (exact, substring, suffix, prefix, subdir, domain)
– regular expression
– hex block

<flags>
-i : ignore case during matching of all subsequent patterns.
-m : use a specific pattern matching method
-n : forbid the DNS resolutions
-u : force the unique id of the ACL
— : force end of flags. Useful when a string looks like one of the flags.

[operator]
匹配整數值:eq、ge、gt、le、lt

匹配字符串:
– exact match (-m str) : the extracted string must exactly match the patterns ;
– substring match (-m sub) : the patterns are looked up inside the extracted string, and the ACL matches if any of them is found inside ;
– prefix match (-m beg) : the patterns are compared with the beginning of the extracted string, and the ACL matches if any of them                                                            matches.
– suffix match (-m end) : the patterns are compared with the end of the extracted string, and the ACL matches if any of them matches.
– subdir match (-m dir) : the patterns are looked up inside the extracted string, delimited with slashes (「/」), and the ACL matches if any of                                                them matches.
– domain match (-m dom) : the patterns are looked up inside the extracted string, delimited with dots (「.」), and the ACL matches if any of                                                      them matches.

acl做爲條件時的邏輯關係:
– AND (implicit)
– OR (explicit with the 「or」 keyword or the 「||」 operator)
– Negation with the exclamation mark (「!」)

if invalid_src invalid_port
if invalid_src || invalid_port
if ! invalid_src invalid_port

<criterion> :
dst : ip
dst_port : integer
src : ip
src_port : integer

acl invalid_src src 172.16.200.2​

path : string
This extracts the request’s URL path, which starts at the first slash and ends before the question mark (without the host part).
/path;<params>

path : exact string match
path_beg : prefix match
path_dir : subdir match
path_dom : domain match
path_end : suffix match
path_len : length match
path_reg : regex match
path_sub : substring match

 

path_beg /images/
path_end .jpg .jpeg .png .gif
path_reg ^/images.*\.jpeg$
path_sub image 
path_dir jpegs
path_dom ilinux​

/images/jpegs/20180312/logo.jpg

url : string
This extracts the request’s URL as presented in the request. A typical use is with prefetch-capable caches, and with portals which need to aggregate multiple information from databases and keep them in caches.

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
This extracts the last occurrence of header <name> in an HTTP request.

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

示例:
acl bad_curl hdr_sub(User-Agent) -i curl
block if bad_curl

status : integer
Returns an integer containing the HTTP status code in the HTTP response.

Pre-defined ACLs
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

HAProxy:global, proxies(fronted, backend, listen, defaults)
balance:
roundrobin, static-rr
leastconn
first
source
hdr(<name>)
uri (hash-type)
url_param

Nginx調度算法:ip_hash, hash, leastconn,
lvs調度算法:
rr/wrr/sh/dh, lc/wlc/sed/nq/lblc/lblcr

基於ACL的動靜分離示例:
frontend web *:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js .html .txt .htm

use_backend staticsrvs if url_static
default_backend appsrvs

backend staticsrvs
balance roundrobin
server stcsrv1 172.16.100.6:80 check

backend appsrvs
balance roundrobin
server app1 172.16.100.7:80 check
server app1 172.16.100.7:8080 check

listen stats
bind :9091
stats enable
stats auth admin:admin
stats admin if TRUE

配置HAProxy支持https協議:
1 支持ssl會話;
bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE

crt後的證書文件要求PEM格式,且同時包含證書和與之匹配的全部私鑰;

cat demo.crt demo.key > demo.pem

2 把80端口的請求重向定443;
bind *:80
redirect scheme https if !{ ssl_fc }

另外一種配置:對非ssl的任何url的訪問通通定向至https主機的主頁;
redirect location https://172.16.0.67/ if !{ ssl_fc }

3 如何向後端傳遞用戶請求的協議和端口
http_request set-header X-Forwarded-Port %[dst_port]
http_request add-header X-Forwared-Proto https if { ssl_fc }

配置時經常使用的功能:
http –> https

mode http
壓縮、條件式轉發、算法、stats page、自定義錯誤頁、訪問控制、日誌功能
最大併發鏈接;
global, defaults, frontend, listen, server
基於cookie的session粘滯
後端主機的健康狀態檢測
請求和響應報文首部的操縱

實踐(博客)做業:
http:
(1) 動靜分離部署wordpress,動靜都要能實現負載均衡,要注意會話的問題;
(2) 在haproxy和後端主機之間添加varnish進行緩存;
(3) 給出設計拓撲,寫成博客;

(4) haproxy的設定要求:
(a) stats page,要求僅能經過本地訪問使用管理接口;
(b) 動靜分離;
(c) 分別考慮不一樣的服務器組的調度算法;
(4) 壓縮合適的內容類型;

 

 

haproxy 超時機制

 


<pre name="code" class="python">option redispatch option redispatch 是否容許從新分配在session 失敗後

option abortonclose 丟棄因爲客戶端等待時間過長而關閉鏈接但仍在haproxy等待隊列中的請求
option abortonclose
#當服務器負載很高的時候,自動結束掉當前隊列處理比較久的連接 
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
option abortonclose
maxconn 65535
timeout connect 5000
timeout client 50000
timeout server 50000
timeout check 5s
stats refresh 30s
timeout http request :在客戶端創建鏈接但不請求數據時,關閉客戶端鏈接
timeout queue :等待最大時長
timeout connect: 定義haproxy將客戶端請求轉發至後端服務器所等待的超時時長
timeout client:客戶端非活動狀態的超時時長
timeout server:客戶端與服務器端創建鏈接後,等待服務器端的超時時長,
timeout http-keep-alive :定義保持鏈接的超時時長
timeout check:健康狀態監測時的超時時間,太短會誤判,過長資源消耗
client_timeout 是 app 鏈接 haproxy的時間
server_timeout 是haproxy 鏈接後端的時間.
目前發現 超時後,前臺一個點擊 haproxy 會收到兩個相同的請求,緣由待查明。
設置 5秒超時時:
timeout connect 5000
timeout client 50000
timeout server 50000

timeout check 5s
stats refresh 30s



 

操做步驟就是:
1)131和132虛擬機上關閉防火牆,分別執行while true; do echo -e 'HTTP/1.0 200 OK\r\n\r\nserver_153' | sudo nc -l -p 80 ; done 
2)在另一臺ip爲129的虛擬機上屢次使用wget http://10.192.74.160 訪問 
3)131,132上面觀察包的處理狀況

腳本就是操做步驟中的這個:while true; do echo -e 'HTTP/1.0 200 OK\r\n\r\nserver_153' | sudo nc -l -p 80 ; done  

相關文章
相關標籤/搜索