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 可以配置單個前端和多個後端的簡單設計;這裏配置的拓撲爲如下圖:
環境配置爲下表:
角色 | IP地址 | 軟件 | 操作系統 |
負載均衡器 | 172.18.29.131 | haproxy | CentOS 7 |
web真實主機1 | 172.18.29.132 | httpd | CentOS 7 |
web真實主機2 | 172.18.29.133 | httpd | 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服務器了!如圖所示:
二、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。狀態如圖:
三、詳細配置前端
ACL作爲前端後端後端連接器,可以靈活把握報文流向,這裏先介紹前端和後端的簡單定義,再將使用ACL 調度機制。
示例:做一個簡單動靜分離:分離動態php頁面到後端lamp服務器上,靜態內容則調度到後端web站點上予以響應。
結構圖:
物理添加兩個lamp服務器,配置如下:
角色 | IP地址 | 軟件 | OS |
phpsrv1 | 172.18.29.141 | lamp | CentOS 6.6 |
phpsrv1 | 172/..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
四、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由於源地址沒變,則調度不再變化。
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:
參數配置中: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不指定,也就是基於權重取模計算。
這裏只介紹到這裏,如果錯誤,請批評指教。