Haproxy 配置詳解

    haproxy是一款高性能的負載均衡器,它提供後端高可用性、負載均衡以及基於TCP和http應用反向代理,支持虛擬主機的快速、可靠的解決方案。Haproxy特別適用於高負載web站點,在時下的硬件上完全可以支持數以萬計的併發鏈接。並且他的運行模式使得它整合簡單、安全,可以保護你的web服務器不被暴露在網絡中。

        Haproxy是事件驅動、單一進程模型,此模型支持非常大的併發連接數。模型的弊端是:在多核心繫統上,這些程序通常擴展性差。

一、haproxy 安裝配置

    haproxy從CentOS 6.4加入了rh系的base源中,可以說是紅帽的主流技術。可以看的出它性能的強悍。YUM安裝即可,配置文件也不多,雖然宣傳的特性墮入牛毛,從配置上看可以說是比較好配置的了。

/etc/haproxy/haproxy.cfg
/etc/sysconfig/haproxy
/usr/bin/halog
/usr/bin/iprange
/usr/lib/systemd/system/haproxy.service
/usr/sbin/haproxy
/usr/sbin/haproxy-systemd-wrapper
/usr/share/haproxy/400.http               
/usr/share/haproxy/403.http
/usr/share/haproxy/408.http
/usr/share/haproxy/500.http
/usr/share/haproxy/502.http
/usr/share/haproxy/503.http
/usr/share/haproxy/504.http

    它生成配置文件較少,主要是haproxy.conf文件,其他文件不用配置,下面還有很多狀態頁面,它可以利用ACL攔截報文,並返回狀態頁面。

    在配置文件haproxy.conf配置文件中,配置命令格式爲空格區分的:配置段名稱定格寫,配置段選項空一個tab再編寫,配置沒有符號。

    主要分爲以下幾段配置:

        global:配置進程及安全相關參數,性能調整相關參數和Debug參數

        proxies:包含四個配置區域

                defaults:各個配置區域的默認配置

                listen:兼顧前端後端的單條配置

                frontend;前端配置

                backend:後端配置

        haproxy作爲透傳式的反向代理,鏈接客戶端和服務器端,frontend即指於客戶端的配置,backend即指於服務器端的配置而ACL就是前端後端的粘合劑。

一、haproxy的簡單代理配置

    listen 可以配置單個前端和多個後端的簡單設計;這裏配置的拓撲爲如下圖:wKioL1dIRS3CjNnAAADqhTfD1SY740.jpg

      環境配置爲下表:

角色
IP地址
軟件
操作系統
負載均衡器
172.18.29.131
haproxy
CentOS 7
web真實主機1
172.18.29.132httpd
CentOS 7
web真實主機2172.18.29.133httpd
CentOS 7

      這裏簡單配置兩臺http訪問器,web服務器配置也可以在此基礎上進行,這裏只做簡答的演示負載均衡效果,配置兩個機器提供不同的主頁顯示,以示區分。

# yum -y install httpd
# echo "<h1>index page @backend srv#</h1>" > /var/www/html/index.html
# systemctl start httpd.service

    保證在131服務器上能夠遠程訪問真實服務器的主頁,修改下/etc/haproxy/haproxy.conf:

global
    log         127.0.0.1 local2            # 全局log配置

    chroot      /var/lib/haproxy            # 設置chroot路徑
    pidfile     /var/run/haproxy.pid
    maxconn     4000                        # 單進程最大連接數
    user        haproxy                     # 配置進程啓動用戶
    group       haproxy
    daemon                                  # 以守護進程模式運行
    
defaults
    mode                    http            # 配置爲http模式
    log                     global          # 配置log爲公共配置日誌
    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


listen  websrvs *:80
    balance roundrobin
    server websrv1 172.18.29.132:80 check
    server websrv2 172.18.29.133:80 check

        這裏defaults和global配置全部沿用默認配置。

        listen 指定前端後端,實例名稱爲websrvs,監聽一個前端任意主機地址的http服務,負載均衡方式位輪詢(roundrobin),分別爲兩個名爲websrv1,websrv2 的後端主機,指定檢測(check)健康情況。此時就啓動haproxy服務,看到端口80已經被haproxy監聽時,就可以簡單請求前端調度器,可以發現已經能夠負載均衡兩個web服務器了!如圖所示:wKioL1dIUHXyI8eNAAFrzGtLc-o217.gif

二、haproxy狀態頁面,狀態頁面

        haproxyadmin時haproxy提供的代理狀態web頁面,同時也是管理頁面。管理者可以輕鬆從中查看當前服務器狀態和經過授權管理後端服務器。配置也相當簡單。

添加行的listen 配置段

listen stats *:9001
    stats enable  
    stats uri /haproxy?stats
    ststs realm "HAProxy stats auth "
    stats auth admin:admin
    stats admin if TRUE

        其中,配置stats爲狀態頁開關,其他選項都有默認值,stats uri爲狀態也請求路徑,也可以修改,此時不做其他配置就可看到狀態頁面了;

    stats realmSTRING 爲授權提示配置。stats auth NAME:PASSWD爲配置管理頁面的明文密碼對;stats admin if TRUE則指示在認證(auth)通過後,顯示管理頁面。由於它的強大功能,所以建議做認證,並修改默認uri。狀態如圖:wKioL1dIVoLwcqulAAVsZeHrVFI942.gif

        

三、詳細配置前端

        ACL作爲前端後端後端連接器,可以靈活把握報文流向,這裏先介紹前端和後端的簡單定義,再將使用ACL 調度機制。

       示例:做一個簡單動靜分離:分離動態php頁面到後端lamp服務器上,靜態內容則調度到後端web站點上予以響應。

    結構圖:

wKioL1dIW8PR2flcAAGAuYpOVtQ518.jpg

      物理添加兩個lamp服務器,配置如下:

角色
IP地址
軟件
OS
phpsrv1
172.18.29.141
lamp
CentOS 6.6
phpsrv1172/..18.29.142
lamp
CentOS 6.6

        初始化lamp環境,這裏使用模塊化lamp環境:

yum -y install httpd php  
echo "index.php Page @  phpsrv# <?php  phpinfo(); ?>" > /var/www/html/index.php
service httpd restart

        在調度器端保證測試請求phpsrv1.phpsrv2的index.php頁面。配置haproxy端:

backend websrvs
    balance roundrobin
    server websrv1 172.18.29.132 check weight 1
    server websrv2 172.18.29.133 check weight 2

backend phpsrvs
    balance roundrobin
    server phpsrv1 172.18.29.141 check weight 1
    server phpsrv2 172.18.29.142 check weight 2

frontend
    bind *:80
    acl php_pages path_end -i .php

    use_backend php_srvs if php_pages
    default_backend websrvs

wKiom1dIat_j4BapAAHv-JHow1c831.gif

四、haproxy調度算法演示

        haroxy負載均衡算法,除了Nginx中同樣常見的roundrobin,leastconn,源地址哈希,等方法,還可以基於cookie粘性完成持久鏈接。

    1.roundrobin

        前面爲了演示效果,用的都是roundrobin 的調度算法;roundrobin是動態算法,可以動態調整負載加權,使後端服務器慢啓動,不至於大量請求涌進來,造成阻塞。算法實現中後端主機數限制爲4095臺。

    2.static-rr :靜態的輪詢,不支持慢啓動機制,後端主機改變權值,那麼需要重新啓動haproxy服務,後端主機數目不限。

    3. leastconn

        在保持鏈接中,長連接會體現出最少鏈接的調度算法。

示例:對ssh服務做調度,採用最少連接算法

listen sshsrvs *:20002
   balance leastconn
   mode tcp
   server sshsrv1 172.18.29.132:22 check
   server sshsrv2 172.18.29.133:22 check

使用ssh -p [email protected] 可以分別鏈接到132,133兩個服務器;且連接上的都是最少鏈接的真實服務器。

# ssh -p 20002 [email protected]
[email protected]'s password: 
Last login: Fri May 27 08:56:35 2016 from 172.18.29.131
[root@CentOS7_133 ~]# 

# 可以看到主機名爲133,再次從另一個客戶端鏈接
# ssh -p 20002 [email protected]
[email protected]'s password: 
Last login: Fri May 27 08:56:35 2016 from 172.18.29.131
[root@CentOS7_132 ~]#

    4.source 源地址hash算法

    對比使用roundrobin和source調度算法

backend websrvs
    balance source
    server websrv1 172.18.29.132:80 check weight 1
    server websrv2 172.18.29.133:80 check weight 2

backend phpsrvs
    balance roundrobin
    server phpsrv1 172.18.29.141:80 check
    server phpsrv2 172.18.29.142:80 check

frontend splitsrvs
    bind *:80
    option httpchk
    acl phppages path_end -i .php

    use_backend phpsrvs if phppages
    default_backend websrvs

    結果如圖:可以看出roundrobin算法調度輪詢請求,而source由於源地址沒變,則調度不再變化。

wKioL1dIcnfwtF1IAAHbpwuzCfA552.gif

    5.uri 根據URL中後半部分選擇算法,這裏設置不同頁面test1-test10.html作爲測試

    執行腳本,創建10個index頁面:

for  i  in {1..10};do  echo “index$1.html  @ websrv# ” > /var/www/html/index$1.html ;done
# ls /var/www/html/index
index10.html  index3.html   index6.html   index9.html   
index1.html   index4.html   index7.html   index.html    
index2.html   index5.html   index8.html   index.php

haproxy 配置:
backend websrvs
    balance uri
    server websrv1 172.18.29.132:80 check
    server websrv2 172.18.29.133:80 check

        多次請求多個頁面可以發現調度uri調度運行調度:

[root@CentOS7_02_131 haproxy]# curl http://172.18.29.131/index1.html
index1 Page@websrv2
[root@CentOS7_02_131 haproxy]# curl http://172.18.29.131/index1.html
index1 Page@websrv2
[root@CentOS7_02_131 haproxy]# curl http://172.18.29.131/index1.html
index1 Page@websrv2
[root@CentOS7_02_131 haproxy]# curl http://172.18.29.131/index2.html
index2 Page@websrv1
[root@CentOS7_02_131 haproxy]# curl http://172.18.29.131/index2.html
index2 Page@websrv1
[root@CentOS7_02_131 haproxy]# curl http://172.18.29.131/index2.html
index2 Page@websrv1
[root@CentOS7_02_131 haproxy]# curl http://172.18.29.131/index3.html
index3 Page@websrv2
[root@CentOS7_02_131 haproxy]# curl http://172.18.29.131/index3.html
index3 Page@websrv2
[root@CentOS7_02_131 haproxy]# curl http://172.18.29.131/index3.html
index3 Page@websrv2

   6.hdr(<name>) :根據請求報文中的<name>標識的頭部值進行hash計算

    示例:這裏使用hdr(Host)進行測試:

設置兩個域名解析:將172.18.29.131設置爲不同的域名:

vim /etc/hots

172.18.29.131 www.magedu.com
172.18.29.131 bbs.magedu.com
172.18.29.131 web.magedu.com

修改調度方式:

backend websrvs
    balance hdr(Host)
    server websrv1 172.18.29.132:80 check
    server websrv2 172.18.29.133:80 check

再次請求報文

[root@CentOS7_02_131 haproxy]# curl http://www.magedu.com/
<h1>iunex.html Page @websrv2</h1>
[root@CentOS7_02_131 haproxy]# curl http://bbs.magedu.com/
<h1>iunex.html Page @websrv2</h1>
[root@CentOS7_02_131 haproxy]# curl http://bbs.magedu.com/
<h1>iunex.html Page @websrv2</h1>
[root@CentOS7_02_131 haproxy]# curl http://web.magedu.com/
“index.html @ websrv# ”
[root@CentOS7_02_131 haproxy]# curl http://web.magedu.com/
“index.html @ websrv# ”
[root@CentOS7_02_131 haproxy]# curl http://web.magedu.com/
“index.html @ websrv# ”

        可以看出根據請求報文的Host首部,做了負載調度,這種情況主要用於虛擬主機的調度。

7.基於用戶端cookie調度

        haproxy可向響應報文中設置“Set-Cookie”頭信息,設置有關調度的頭信息:以後用戶每次根據cookie信息請求服務器端,中間調度器,根據調度的頭信息,保持用戶端的會話,從而保持會話粘性。

        haproxy配置:

backend websrvs
    balance roundrobin
    cookie SERVERID insert indirect nocache
    server websrv1 172.18.29.132:80 check  cookie websrv1
    server websrv2 172.18.29.133:80 check  cookie websrv2

此時一定要用瀏覽器查看,可以看到下面方框內請求報文攜帶了cookie,且設置的內容正是我們設置的cookie:

wKiom1dIejniQcu8AAPzARZIAbQ738.jpg

        參數配置中:backend中配置的cookie指令:插入指定名稱(示例:SERVERID),不將cookie交給後端真實主機(indirect),不緩存(nocache),這裏不設置緩存是爲了在外網用戶使用正向代理緩存時不緩存cookie信息,一面正向代理後側的用戶全都使用該cookie訪問調度器而造成會話粘性失敗。另外這裏不能使用curl命令測試,curl命令不指定cookie會退化爲輪詢算法。

        以上算法都會使用hash功能的調度,都會有動態靜態兩種計算方法,計算方法有hash-type 命令指定:

hash-type <method> <function> <modifier>

        <method>

                map-based:基於權重取模計算

                consistent:一致性hash算法,可以有效降低hash,部分服務器失效後的雪崩效應。

        默認method爲map-based,function爲sdbm,modifier不指定,也就是基於權重取模計算。

        這裏只介紹到這裏,如果錯誤,請批評指教。


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