專注高端網(wǎng)站建設seo 專業(yè)
Haproxy搭建負載均衡
- 一、常見的Web集群調度器
- 二、Haproxy介紹
- 1、Haproxy應用分析
- 2、Haproxy的主要特性
- 3、Haproxy負載均衡策略
- 三、LVS、Nginx、Haproxy之間的區(qū)別
- 四、Haproxy搭建Web群集
- 1、Haproxy服務器部署
- 2、節(jié)點服務器部署
- 3、測試Web群集
- 五、日志定義
- 1、方法一
- 2、方法二
- 六、使用 Keepalived 實現(xiàn) Haproxy 高可用
- 七、內(nèi)核優(yōu)化
一、常見的Web集群調度器
目前常見的Web集群調度器分為軟件和硬件:
- 軟件通常使用開源的LVS、Haproxy、Nginx
- LVS性能最好,但是搭建相對復雜;Nginx的upstream模塊支持群集功能,但是對群集節(jié)點健康檢查功能不強,高并發(fā)性能沒有Haproxy好
- 硬件一般使用表較多的是F5、Array,也有很多人使用國內(nèi)的一些產(chǎn)品,如梭子魚、綠盟等
二、Haproxy介紹
Haproxy是可提供高可用性、負載均衡以及基于TCP和HTTP應用的代理,是免費、快速并且可靠的一種解決方案。Haproxy非常適用于并發(fā)大(并發(fā)達1w以上)web站點,這些站點通常又需要會話保持或七層處理。Haproxy的運行模式使得它可以很簡單安全的整合至當前的架構中,同時可以保護web服務器不被暴露到網(wǎng)絡上。
1、Haproxy應用分析
- LVS在企業(yè)應用中康復在能力很強,但存在不足
- LVS不支持正則處理,不能實現(xiàn)動靜分離
- 對于大型網(wǎng)站,LVS的實施配置復雜,維護成本相對較高
- Haproxy是一款可提供高可用、負載均衡、及基于TCP和HTTP應用的代理的軟件
- 適用于負載大的Web站點
- 運行在硬件上可支持數(shù)以萬計的并發(fā)連接的連接請求
2、Haproxy的主要特性
- 可靠性和穩(wěn)定性非常好,可以與硬件級的F5負載均衡設備相媲美
- 最高可以同時維護40000-50000個并發(fā)連接,單位時間內(nèi)處理的最大請求數(shù)為20000個,最大處理能力可達10Git/s;
- 支持多達8種負載均衡算法
- 支持Session會話保持,Cookie的引導;
- 支持通過獲取指定的url來檢測后端服務器的狀態(tài);
- 支持虛擬主機功能,從而實現(xiàn)web負載均衡更加靈活;
- 支持連接拒絕、全透明代理等獨特的功能;
- 擁有強大的ACL支持,用于訪問控制;
- 支持TCP和HTTP協(xié)議的負載均衡轉發(fā);
- 支持客戶端的keepalive功能,減少客戶端與haproxy的多次三次握手導致資源浪費,讓多個請求在一個tcp連接中完成
3、Haproxy負載均衡策略
策略 | 作用 |
---|---|
roundrobin | 表示簡單的輪詢 |
static-rr | 表示根據(jù)權重 |
leastconn | 表示最少連接者先處理 |
source | 表示根據(jù)請求源IP |
uri | 表示根據(jù)請求的URI,做cdn需使用; |
url_param | 表示根據(jù)請求的URl參數(shù)’balance url_param’ requires an URL parameter name |
hdr(name) | 表示根據(jù)HTTP請求頭來鎖定每一次HTTP請求; |
rdp-cookie(name) | 表示根據(jù)cookie(name)來鎖定并哈希每一次TCP請求。 |
三、LVS、Nginx、Haproxy之間的區(qū)別
- LVS基于Linux操作系統(tǒng)內(nèi)核實現(xiàn)軟負載均衡,而HAProxy和Nginx是基于第三方應用實現(xiàn)的軟負載均衡;
- LVS是可實現(xiàn)4層的IP負載均衡技術,無法實現(xiàn)基于目錄、URL的轉發(fā)。而HAProxy和Nginx都可以實現(xiàn)4層和7層技術,HAProxy可提供TCP和HTTP應用的負載均衡綜合解決方案;
- LVS因為工作在ISO模型的第四層,其狀態(tài)監(jiān)測功能單一,而HAProxy在狀態(tài)監(jiān)測方面功能更豐富、強大,可支持端口、URL、腳本等多種狀態(tài)檢測方式;
- HAProxy功能強大,單純從效率上來講HAProxy會比Nginx有更出色的負載均衡速度,在并發(fā)處理上也是優(yōu)于Nginx的。但整體性能低于4層模式的LVS負載均衡;
- Nginx主要用于Web服務器或緩存服務器。Nginx的upstream模塊雖然也支持群集功能,但是性能沒有LVS和Haproxy好,對群集節(jié)點健康檢查功能不強,只支持通過端口來檢測,不支持通過URL來檢測。
四、Haproxy搭建Web群集
Haproxy服務器:192.168.154.13
Nginx 服務器1:192.168.154.14
Nginx 服務器2:192.168.154.15
客戶端:192.168.154.11
1、Haproxy服務器部署
- 關閉防火墻,將安裝Haproxy所需軟件包傳到/opt目錄下
systemctl stop firewalld
setenforce 0wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.2.tar.gz
- 安裝 Haproxy
//編譯安裝
yum install -y pcre-devel bzip2-devel gcc gcc-c++ maketar zxvf haproxy-1.7.2.tar.gz
cd haproxy-1.7.2/
make TARGET=linux2628 PREFIX=/usr/local/haproxy
make install PREFIX=/usr/local/haproxy
參數(shù)說明:
TARGET=linux26 #內(nèi)核版本,
#使用uname -r查看內(nèi)核,如:2.6.18-371.el5,此時該參數(shù)用TARGET=linux26;kernel大于2.6.28的用TARGET=linux2628
- Haproxy服務器配置
useradd -M -s /sbin/nologin haproxymkdir -p /usr/local/haproxy/conf
cd /usr/local/haproxy/conf//yum安裝
yum install -y haproxy
HAProxy 的配置文件共有 5 個域:
- global:用于配置全局參數(shù)
- default:用于配置所有frontend和backend的默認屬性
- frontend:用于配置前端服務(即HAProxy自身提供的服務)實例
- backend:用于配置后端服務(即HAProxy后面接的服務)實例組
- listen:frontend + backend的組合配置,可以理解成更簡潔的配置方法,frontend域和backend域中所有的配置都可以配置在listen域下
vim haproxy.cfg
global #全局配置,主要用于定義全局參數(shù),屬于進程級的配置,通常和操作系統(tǒng)配置有關#將info(及以上)的日志發(fā)送到rsyslog的local0接口,將warning(及以上)的日志發(fā)送到rsyslog的local1接口log 127.0.0.1 local0 infolog 127.0.0.1 local1 warning maxconn 30000 #最大連接數(shù),HAProxy 要求系統(tǒng)的 ulimit -n 參數(shù)大于 maxconn*2+18#chroot /var/lib/haproxy #修改haproxy工作目錄至指定目錄,一般需將此行注釋掉pidfile /var/run/haproxy.pid #指定保存HAProxy進程號的文件user haproxy #以指定的用戶名身份運行haproxy進程group haproxy #以指定的組名運行haproxy,以免因權限問題帶來風險daemon #讓haproxy以守護進程的方式工作于后臺#nbproc 1 #指定啟動的haproxy進程個數(shù),只能用于守護進程模式的haproxy,默認只啟動一個進程。haproxy是單進程、事件驅動模型的軟件,單進程下工作效率已經(jīng)非常好,不建議開啟多進程spread-checks 2 #在haproxy后端有著眾多服務器的場景中,在精確的時間間隔后統(tǒng)一對眾服務器進行健康狀況檢查可能會帶來意外問題;此選項用于將其檢查的時間間隔長度上增加或減小一定的隨機時長;默認為0,官方建議設置為2到5之間。defaults #配置默認參數(shù),這些參數(shù)可以被用到listen,frontend,backend組件 log global #所有前端都默認使用global中的日志配置mode http #模式為http(7層代理http,4層代理tcp)option http-keep-alive #使用keepAlive連接,后端為靜態(tài)建議使用http-keep-alive,后端為動態(tài)應用程序建議使用http-server-closeoption forwardfor #記錄客戶端IP在X-Forwarded-For頭域中,haproxy將在發(fā)往后端的請求中加上"X-Forwarded-For"首部字段option httplog #開啟httplog,在日志中記錄http請求、session信息等。http模式時開啟httplog,tcp模式時開啟tcplogoption dontlognull #不在日志中記錄空連接option redispatch #當某后端down掉使得haproxy無法轉發(fā)攜帶cookie的請求到該后端時,將其轉發(fā)到別的后端上option abortonclose #當服務器負載很高的時候,自動結束掉當前隊列處理比較久的鏈接maxconn 20000 #最大連接數(shù),“defaults”中的值不能超過“global”段中的定義retries 3 #定義連接后端服務器的失敗重連次數(shù),連接失敗次數(shù)超過此值后會將對應后端服務器標記為不可用#contimeout 5000 #設置連接超時時間,默認單位是毫秒#clitimeout 50000 #設置客戶端超時時間,默認單位是毫秒#srvtimeout 50000 #設置服務器超時時間,默認單位是毫秒timeout http-request 2s #默認http請求超時時間,此為等待客戶端發(fā)送完整請求的最大時長,用于避免類DoS攻擊。haproxy總是要求一次請求或響應全部發(fā)送完成后才會處理、轉發(fā)timeout queue 3s #默認客戶端請求在隊列中的最大時長timeout connect 1s #默認haproxy和服務端建立連接的最大時長,新版本中替代contimeout,該參數(shù)向后兼容timeout client 10s #默認和客戶端保持空閑連接的超時時長,在高并發(fā)下可稍微短一點,可設置為10秒以盡快釋放連接,新版本中替代clitimeouttimeout server 2s #默認和服務端保持空閑連接的超時時長,局域網(wǎng)內(nèi)建立連接很快,所以盡量設置短一些,特別是高并發(fā)時,新版本中替代srvtimeouttimeout http-keep-alive 10s #默認和客戶端保持長連接的最大時長。優(yōu)先級高于timeout http-request 也高于timeout clienttimeout check 2s #和后端服務器成功建立連接后到最終完成檢查的最大時長(不包括建立連接的時間,只是讀取到檢查結果的時長)frontend http-in #定義前端域bind *:80 #設置監(jiān)聽地址和端口,指定為*或0.0.0.0時,將監(jiān)聽當前系統(tǒng)的所有IPv4地址maxconn 18000 #定義此端口上的maxconnacl url_static1 path_beg -i /static /images #定義ACL,當uri以定義的路徑開頭時,ACL[url_static1]為trueacl url_static2 path_end -i .jpg .jpeg .gif .png .html .htm .txt #定義ACL,當uri以定義的路徑結尾時,ACL[url_static2]為trueuse_backend ms1 if url_static1 #當[url_static1]為true時,定向到后端域ms1中use_backend ms2 if url_static2 #當[url_static2]為true時,定向到后端域ms2中default_backend dynamic_group #其他情況時,定向到后端域dynamic_group中backend ms1 #定義后端域ms1balance roundrobin #使用輪詢算法option httpchk GET /test.html #表示基于http協(xié)議來做健康狀況檢查,只有返回狀態(tài)碼為2xx或3xx的才認為是健康的,其余所有狀態(tài)碼都認為不健康。不設置該選項時,默認采用tcp做健康檢查,只要能建立tcp就表示健康。server ms1.inst1 192.168.80.100:80 maxconn 5000 check inter 2000 rise 2 fall 3server ms1.inst2 192.168.80.100:81 maxconn 5000 check #同上,inter 2000 rise 2 fall 3是默認值,可以省略backend ms2 #定義后端域ms2balance roundrobinoption httpchk GET /test.htmlserver ms2.inst1 192.168.80.101:80 maxconn 5000 checkserver ms2.inst2 192.168.80.101:81 maxconn 5000 checkbackend dynamic_group #定義后端域dynamic_groupbalance roundrobinoption http-server-closecookie HA_STICKY_dy insert indirect nocache server appsrv1 192.168.80.100:8080 cookie appsrv1 maxconn 5000 checkserver appsrv2 192.168.80.101:8080 cookie appsrv2 maxconn 5000 checklisten stats #定義監(jiān)控頁面bind *:1080 #綁定端口1080stats enable #啟用統(tǒng)計報告監(jiān)控stats refresh 30s #每30秒更新監(jiān)控數(shù)據(jù)stats uri /stats #訪問監(jiān)控頁面的uristats realm HAProxy\ Stats #監(jiān)控頁面的認證提示stats auth admin:admin #監(jiān)控頁面的用戶名和密碼
-
balance roundrobin #負載均衡調度算法
- roundrobin:輪詢算法;leastconn:最小連接數(shù)算法;source:來源訪問調度算法,類似于nginx的ip_hash
-
check 指定此參數(shù)時,HAProxy 將會對此 server 執(zhí)行健康檢查,檢查方法在 option httpchk 中配置。同時還可以在 check 后指定 inter, rise, fall 三個參數(shù), 分別代表健康檢查的周期、連續(xù)幾次成功認為 server UP、連續(xù)幾次失敗認為 server DOWN,默認值是 inter 2000 rise 2 fall 3
- inter 2000 #表示啟用對此后端服務器執(zhí)行健康檢查,設置健康狀態(tài)檢查的時間間隔,單位為毫秒
- rise 2 #設定server從離線狀態(tài)重新上線需要成功檢查的次數(shù);不指定默認為2
- fall 3 #表示連續(xù)三次檢測不到心跳頻率則認為該節(jié)點失效
-
cookie:在 backend server 間啟用基于 cookie 的會話保持策略,最常用的是 insert 方式。
-
cookie HA_STICKY_dy insert indirect nocache,指 HAProxy 將在響應中插入名為 HA_STICKY_dy 的 cookie,其值為對應的 server 定義中指定的值,并根據(jù)請求中此 cookie 的值決定轉發(fā)至哪個 server。
-
indirect #代表如果請求中已經(jīng)帶有合法的 HA_STICK_dy cookie,則 HAProxy 不會在響應中再次插入此 cookie
-
nocache #代表禁止鏈路上的所有網(wǎng)關和緩存服務器緩存帶有 Set-Cookie 頭的響應
-
-
若節(jié)點配置后帶有“backup”表示該節(jié)點只是個備份節(jié)點,僅在所有在線節(jié)點都失效該節(jié)點才啟用。不攜帶“backup”,表示為在線節(jié)點,和其它在線節(jié)點共同提供服務。
- 添加haproxy 系統(tǒng)服務
vim /etc/init.d/haproxy
#!/bin/bash
#chkconfig: 2345 90 30
#description: Haproxy Service Control ScriptPROGDIR=/usr/local/haproxy
PROGNAME=haproxy
DAEMON=$PROGDIR/sbin/$PROGNAME
CONFIG=$PROGDIR/conf/$PROGNAME.cfg
PIDFILE=/var/run/$PROGNAME.pid
DESC="HAProxy daemon"
SCRIPTNAME=/etc/init.d/$PROGNAME#Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0start()
{echo -e "Starting $DESC: $PROGNAME\n"$DAEMON -f $CONFIGecho "......"
}stop()
{echo -e "Stopping $DESC: $PROGNAME\n"haproxy_pid="$(cat $PIDFILE)"kill $haproxy_pidecho "......"
}restart()
{echo -e "Restarting $DESC: $PROGNAME\n"$DAEMON -f $CONFIG -p $PIDFILE -sf $(cat $PIDFILE)echo "......"
}case "$1" in
start)start;;stop)stop;;restart)restart;;*)echo "Usage: $SCRIPTNAME {start|stop|restart}"exit 1;;
esacexit 0cd /etc/init.d/
chmod +x haproxy
chkconfig --add /etc/init.d/haproxyln -s /usr/local/haproxy/sbin/haproxy /usr/sbin/haproxy
service haproxy start 或 /etc/init.d/haproxy start
2、節(jié)點服務器部署
systemctl stop firewalld
setenforce 0yum install -y pcre-devel zlib-devel gcc gcc-c++ make useradd -M -s /sbin/nologin nginxcd /opt
tar zxvf nginx-1.12.0.tar.gz -C /opt/cd nginx-1.12.0/
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx && make && make installmake && make install---192.168.154.14---
echo "this is kgc web" > /usr/local/nginx/html/test.html---192.168.154.15---
echo "this is benet web" > /usr/local/nginx/html/test.htmlln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/nginx #啟動nginx 服務
3、測試Web群集
在客戶端使用瀏覽器打開 http://192.168.154.13/test.html ,不斷刷新瀏覽器測試負載均衡效果
訪問一下監(jiān)控頁面 http://192.168.154.13:1080/stats 并提示輸入用戶名密碼 admin/admin
五、日志定義
默認 haproxy 的日志是輸出到系統(tǒng)的 syslog 中,查看起來不是非常方便,為了更好的管理 haproxy 的日志,我們在生產(chǎn)環(huán)境中一般單獨定義出來。需要將 haproxy 的 info 及 notice 日志分別記錄到不同的日志文件中。
1、方法一
vim /etc/haproxy/haproxy.cfg
globallog /dev/log local0 infolog /dev/log local0 notice......defaults......log global......#需要修改rsyslog配置,為了便于管理。將haproxy相關的配置獨立定義到haproxy.conf,并放到/etc/rsyslog.d/下,rsyslog啟動時會自動加載此目錄下的所有配置文件。
vim /etc/rsyslog.d/haproxy.conf
if ($programname == 'haproxy' and $syslogseverity-text == 'info')
then -/var/log/haproxy/haproxy-info.log
&~
if ($programname == 'haproxy' and $syslogseverity-text == 'notice')
then -/var/log/haproxy/haproxy-notice.log
&~#說明:
這部分配置是將haproxy的info日志記錄到/var/log/haproxy/haproxy-info.log下,將notice日志記錄到/var/log/haproxy/haproxy-notice.log下?!?amp;~”表示當日志寫入到日志文件后,rsyslog停止處理這個信息。service rsyslog restart
service haproxy restarttail -f /var/log/haproxy/haproxy-info.log #查看haproxy的訪問請求日志信息
2、方法二
#修改haproxy.cfg,將info及以上級別的日志發(fā)送到rsyslog的local0接口,將warning及以上級別的日志發(fā)送到rsyslog的local1接口
vim /etc/haproxy/haproxy.cfg
global......log 127.0.0.1 local0 infolog 127.0.0.1 local1 warning......defaults......log global......#注:信息級日志會打印HAProxy 的每一條請求處理,會占用大量的磁盤空間,在生產(chǎn)環(huán)境中,將日志級別調整為notice#為 rsyslog 添加 haproxy 日志的配置
mkdir /var/log/haproxyvim /etc/rsyslog.d/haproxy.conf
$ModLoad imudp
$UDPServerRun 514
$FileCreateMode 0644 #日志文件的權限
$FileOwner haproxy #日志文件的owner
local0.* /var/log/haproxy/haproxy.log #local0接口對應的日志輸出文件
local1.* /var/log/haproxy/haproxy_warn.log #local1接口對應的日志輸出文件#修改 rsyslog 的啟動參數(shù)
vim /etc/sysconfig/rsyslog
......
SYSLOGD_OPTIONS="-c 2 -r -m 0"#重啟 rsyslog 和 HAProxy
service rsyslog restart
service haproxy restarttail -f /var/log/haproxy/haproxy.log
六、使用 Keepalived 實現(xiàn) Haproxy 高可用
yum install -y keepalivedvim /etc/keepalived/check_haproxy.sh
#!/bin/bash
#使用killall -0檢查haproxy實例是否存在,性能高于ps命令
if ! killall -0 haproxy; thensystemctl stop keepalived
fichmod +x /etc/keepalived/check_haproxy.shvim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {router_id LVS_HA1 #虛擬路由名稱
}#HAProxy健康檢查配置
vrrp_script chk_haproxy {script "/etc/keepalived/check_haproxy.sh" #指定健康檢查腳本interval 2 #腳本運行周期weight 2 #每次檢查的加權權重值
}#虛擬路由配置
vrrp_instance VI_1 {state MASTER #本機實例狀態(tài),MASTER/BACKUP,備機配置文件中設置BACKUPinterface ens33 #本機網(wǎng)卡名稱,使用ifconfig命令查看virtual_router_id 51 #虛擬路由編號,主備機保持一致priority 100 #本機初始權重,備機設置小于主機的值advert_int 1 #爭搶虛地址的周期,秒virtual_ipaddress {192.168.80.100 #虛地址IP,主備機保持一致}track_script {chk_haproxy #對應的健康檢查配置}
}systemctl start keepalivedip addr#停掉當前MASTER主機的HAProxy實例,進行故障切換測試
service haproxy stop
七、內(nèi)核優(yōu)化
vim /etc/sysctl.conf
#開啟重用。允許將TIME-WAITsockets重用于新的TCP連接,默認0,表示關閉;net.ipv4.tcp_tw_reuse = 1
#用于向外連接的端口范圍。缺省情況下很小net.ipv4.ip_local_port_range = 1024 65535
#SYN隊列長度,記錄尚未收到客戶端確認信息的連接請求的最大值。默認為1024,加大隊列長度可容納更多等待
連接的網(wǎng)絡連接數(shù)。net.ipv4.tcp_max_syn_backlog = 10240
#表示系統(tǒng)同時保持TIME_WAIT最大數(shù)量,如果超過,TIME_WAIT將立刻被清除并打印警告信息。默認180000,此項參數(shù)可控制TIME_WAIT 最大數(shù)量net.ipv4.tcp_max_tw_buckets = 5000
#系統(tǒng)中最多有多少個TCP套接字不被關聯(lián)到任何一個用戶文件句柄上,如超過,連接將即刻被復位并打印警告信息,這個限制僅是為防止簡單的DoS攻擊,不能過分依靠它或人為減小這個值,更應該增加這個值(如果增加內(nèi)存后)net.ipv4.tcp_max_orphans = 3276800
#為打開對端的連接,內(nèi)核需發(fā)送個SYN并附帶個回應前一個SYN的ACK。即三次握手中的第二次握手。該設置決定內(nèi)核放棄連接前發(fā)SYN+ACK包的數(shù)量。net.ipv4.tcp_synack_retries = 3
#如web應用中l(wèi)isten函數(shù)的backlog默認會給我們內(nèi)核參數(shù)的net.core.somaxconn限制到128,而 nginx 定義的 NGX_LISTEN_BACKLOG 默認511,所以有必要調整這個值。
net.core.somaxconn = 32768sysctl -p