Haproxy的基礎知識介紹

    在日常生活中,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的主配置文件中有如下一行指令,是用於定義啓用日誌的:

            wKiom1V0QkTT_ldcAACXQcGPxhQ686.jpg


    

    首先定義日誌文件:

[root@node2 ~]# vim /etc/rsyslog.conf

       此項的啓用,是使用udp監聽:

            wKioL1V0REjQZQtkAAAzbVXUy4k956.jpg

            然後定義日誌位置:

            wKioL1V0RJfQ-psgAAByxaJ_mWA707.jpg

        

    然後重啓日誌服務就會生成haproxy的日誌:

            wKioL1V0ROCBa60gAAB40XYMydg237.jpg



    示例:定義一個簡單的服務代理:       

        在配置中定義後端服務爲appserver,以及兩個後端服務器,一個後端主機位172.16.90.2還有一個172.16.90.3。

                            [

                          root@node0 ~]# vim /etc/haproxy/haproxy.cfg 

                                

              wKioL1V0RVfAzn1_AAGhSqMcnHA953.jpg

    而後,後端服務器啓動http服務,就能得到代理的後面服務器的兩個測試頁面:


                wKiom1V0RFCSY7faAABONqhhuXs404.jpg


                wKiom1V0RGvh63cBAABH6i4rZBI789.jpg

    

下面說下全局配置中的一些參數:

 

“global”配置中的參數爲進程級別的參數,且通常與其運行的OS相關。

 * 進程管理及安全相關的參數

      - chroot <jail dir>:修改haproxy的工作目錄至指定的目錄並在放棄權限之前執行chroot()操作,可                    以提升haproxy的安全級別,不過需要注意的是要確保指定的目錄爲空目錄且                    任何用戶均不能有寫權限;

     - daemon:讓haproxy以守護進程的方式工作於後臺,其等同於“-D”選項的功能,當然,也可以                在命令行中以“-db”選項將其禁用;

   - gid <number>:以指定的GID運行haproxy,建議使用專用於運行haproxyGID,以免因權限問題帶                 來風險;

   - 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: 新的連接請求被派發至具有最少連接數目的後端服務器;在有着較長時間會話          的場景中推薦使用此算法,如LDAPSQL等,其並不太適用於較短會話的應用          層協議,如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定義的;

                默認的配置文件中:

                        wKiom1V0S-bhe7_hAACsiCtcfc4616.jpg     

server <name> <address>[:[port]] [param*]

             <address>ipv4或ipv6;

                          [param*]:

                                  check:啓用對server的健康狀態檢測功能;tcp層的監測;補充類的參數:

                                          inter:時間間隔

                                          rise:上線前的成功檢查次數

                                           fall:下線前的失敗檢查次數                                                

                                   cookie:分配給servercookie信息;

                                               disabled:設置服務器爲“禁用”狀態;

                                   maxconn:最大併發連接數;

                                   maxqueue:等待隊列最大長度;0表示無上限;

                                   minconn:最少併發連接數;

                                   weight:權重;

                 例:

                    wKiom1V0TNzRTKSQAABTib5Ic74818.jpg


bind

 

bind [<address>]:<port_range> [, ...]

bind [<address>]:<port_range> [, ...] interface <interface>

 

此指令僅能用於frontendlisten區段,用於定義一個或幾個監聽的套接字。

 

<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層報文做任何類型的檢查;此爲默認模式,通常用於SSLSSHSMTP等應用;                 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

                  例:

                     wKioL1V0T1OyyoMGAACMucuIyAs779.jpg

                     wKiom1V0TiCxZWkyAATcgf0CsLI207.jpg


儘管“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的粘性,綁定服務器

                          cookieEnable 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 ] 

          定義轉發首部,即轉發真正的客戶端首部到服務器端;可以用於frontendbackenddefaultlisten

            Enable insertion of the X-Forwarded-For header to requests sent to servers

 

例:在haproxy服務器上,定義在backend中,添加option  forwardfor;

        wKioL1V0UVWTps5YAADxYhbONL4068.jpg

        更改後端上游服務器的日誌格式,,用於記錄首部信息需要查看的可以更改:            

wKiom1V0T_6hxEJcAAC1YvP9VNM495.jpg

      得到來自真實客戶端的IP:

        

      wKiom1V0UHGDB9qkAAEQhJ2wHH8094.jpg                 option http-servrt-close:當選擇長了連接時啓用,服務器端主動把後端連接關閉,否則會長                                  時間佔據後端服務器端的連接;

         option http-pretend-keepalive 假裝長連接。即,由於後端服務器不支持長連接,而客戶端與前端                                                HAproxy服務器端是長連接,若後端反饋給前端的是已斷開,則前端也會                                          斷開連接,此命令就是用於假裝後端還是連着。當前端發出請求時,後                                          端服務器可再次啓用。

 

haproxyacl:

 

haproxyACL用於實現基於請求報文的首部、響應報文的內容或其它的環境狀態信息來做出轉發決策,這大大增強了其配置彈性。其配置法則通常分爲兩步,首先去定義ACL,即定義一個測試條件,而後在條件得到滿足時執行某特定的動作,如阻止請求或轉發至某特定的後端。定義ACL的語法格式如下。

 

  acl <aclname> <criterion> [flags] [operator] <value> ...

 

  <aclname>ACL名稱,區分字符大小寫,且其只能包含大小寫字母、數字、-(連接線)_(下劃線)、                 .(點號):(冒號)haproxy中,acl可以重名,這可以把多個測試條件定義爲一個共同的acl

  <criterion>:測試標準,即對什麼信息發起測試;測試方式可以由[flags]指定的標誌進行調整;而有些測             試標準也可以需要爲其在<value>之前指定一個操作符[operator]

  [flags]:目前haproxyacl支持的標誌位有3個:

    -i:不區分<value>中模式字符的大小寫;

    -f:從指定的文件中加載模式;

    --:標誌符的強制結束標記,在模式中的字符串像標記符時使用;

  <value>acl測試條件支持的值有以下四類:

                   整數或整數範圍:如1024:65535表示從102465535;僅支持使用正整數(如果出現類似小數的           標識,其爲通常爲版本測試),且支持使用的操作符有5個,分別爲    eqgegtlelt

   字符串:支持使用“-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是否以jpggifpngcssjs結尾。

 

    acl url_static       path_end       -i .jpg .gif .png .css .js

5.1.7 hdr_beg <string>

 

用於測試請求報文的指定首部的開頭部分是否符合<string>指定的模式。例如,下面的例子用記測試請求是否爲提供靜態內容的主機imgvideodownloadftp

 

    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        


















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章