一、Haproxy概述
一種高效、可靠、免費的高可用及負載均衡軟體,非常适合于高負載站點的七層資料請求。用戶端通過Haproxy代理伺服器獲得站點頁面,而代理伺服器收到客戶請求後根據負載均衡的規則将請求資料轉發給後端真實伺服器,實作了一種事件驅動、單一程序模型,能支援非常大的并發連接配接數。
同一用戶端通路伺服器,Haproxy保持會話的三種方案:
1) Haproxy将用戶端ip進行Hash計算并儲存,由此確定相同IP通路時被轉發到同一真實伺服器上。
2) Haproxy依靠真實伺服器發送給用戶端的cookie資訊進行回話保持。
3) Haproxy儲存真實伺服器的session及伺服器辨別,實作會話保持功能。
二、Haproxy代理模式
四層Tcp代理
:Haproxy僅在用戶端和伺服器之間雙向轉發流量,可用于郵件服務内部協定通信伺服器、Mysql服務等;
七層應用代理
:Haproxy會分析應用層協定,并且能通過運作、拒絕、交換、增加、修改或者删除請求(request)或者回應(reponse)裡指定内容來控制協定。可用于HTTP代理或https代理。
無負載均衡
簡單的無負載均衡Web應用環境, 使用者會直接接入Web伺服器,即kevin.com且其中不存在負載均衡機制。如果單一Web伺服器發生故障,使用者将無法接入該伺服器。另,若多位使用者同時通路該伺服器,且其無法處理該負載,則會出現響應緩慢或者無法接入的情況
四層負載均衡
最為簡單的負載均衡方式,将網絡流量引導至多台伺服器以使用四層(即傳輸層)負載均衡。這種方式會根據IP範圍與端口進行使用者流量轉發(例如:有請求指向http://kevin.com/anything,則該流量将被轉發至backend,即将使用者請求轉發至後端伺服器的web-backend組。被標明的後端伺服器将直接響應使用者請求),web-backend中的全部伺服器都應當擁有同樣的内容, 否則使用者可能會遭遇内容不一緻問題。
七層負載均衡
網絡流量使用7層負載均衡意味着均衡器能夠根據使用者的請求内容将請求轉發至不同後端伺服器。這種方式允許在同一域名及端口上運作多套Web應用伺服器。例如:使用者向kevin.com/blog發送請求,則會被轉發至blog後端,其包含一組運作有同一blog應用的伺服器。其它請求則會被轉發至web-backend,其負責運作其它應用。總的來說,它可以根據“IP+端口”的方式進行負載分流,還可以根據網站的URL、通路域名、浏覽器類别、語言等決定負載均衡的政策。
三、負載均衡LVS、Haproxy、Nginx對比

總結:
大型網站架構
:對性能有嚴格要求的時候可以使用lvs或者硬體F5,單從負載均衡的角度來說,lvs也許會成為主流,更适合現在大型的網際網路公司。
中型網站架構
:對于頁面分離請求有明确規定,并且性能有嚴格要求時,可以使用haproxy。
中小型網站架構
:比如日通路量小于1000萬,需要進行高并發的網站或者對網絡不太嚴格的時候,可以使用nginx。
四、 Haproxy負載均衡算法
HaProxy的負載均衡算法現在具體有如下8種:
roundrobin:
輪詢
static-rr:
權重輪詢
leastconn:
最少連接配接者優先
source:
根據請求源IP,這個跟Nginx的ip_hash機制類似
ri:
根據請求的URI
rl_param:
表示根據請求的URI參數‘balance url_param’requires an URL parameter name;
hdr(name):
根據HTTP請求頭來鎖定每一次HTTP請求
rdp-cookie(name):
根據cookie來鎖定并哈希每一次TCP請求
五.Haproxy的配置
Haproxy的配置過程分為3個主要部分:
- 指令行參數,這是最優先的;
- global(全局)段,設定程序級參數;
- 代理配置段,通常位于default,listen,backend這樣的形式内。配置檔案的文法是由關鍵字後跟可選的一個或者多個參數(參數之間有空格)組成。如果字元串中包含空格,必須用’\’進行轉義。
Haproxy配置中分五大部分:
-
:全局參數配置,程序級的,用來控制Haproxy啟動前的一些程序及系統設定。global
-
:配置一些預設的參數,可以被frontend,backend,listen段內建使用。defaults
-
:用來比對接收客戶所請求的域名,uri等,并針對不同的比對,做不同的請求處理。frontend
-
:定義後端伺服器叢集,以及對後端伺服器叢集的一些權重、隊列、連接配接數等選項的設定,類似于nginx中的upstream子產品。backend
-
:可以了解為frontend和backend的組合體。listen
Haproxy配置檔案的配置方法主要有兩種,一種是由前端(frontend)和後端(backend)配置塊組成,前端和後端都可以有多個。第二種方法是隻有一個listen配置塊來同時實作前端和後端。最常用也是推薦的方法為第一種,即frontend和backend的模式。
1. 配置參數詳解
global # 全局參數global子產品的設定
log 127.0.0.1 local2 # log文法:log <address_1>[max_level_1] # 全局的日志配置,使用log關鍵字,指定使用127.0.0.1上的syslog服務中的local0日志裝置,記錄日志等級為info的日志
chroot /var/lib/haproxy #工作目錄
pidfile /var/run/haproxy.pid #程序pid檔案
maxconn 4000 #最大連接配接數
user haproxy #所屬使用者
group haproxy #所屬使用者組
daemon #以守護程序方式運作haproxy
stats socket /var/lib/haproxy/stats #定義socket套接字,針對線上維護很有幫助
defaults # defaults子產品的設定
mode http #預設的模式{ tcp|http|health},health隻會傳回OK
log global #應用全局的日志配置
option httplog #啟用日志記錄HTTP請求,預設不記錄HTTP請求日志
option dontlognull # 啟用該項,日志中将不會記錄空連接配接。所謂空連接配接就是在上遊的負載均衡器者監控系統為了探測該 服務是否存活可用時,需要定期的連接配接或者擷取某一固定的元件或頁面,或者探測掃描端口是否在監聽或開放等動作被稱為空連接配接;官方文檔中标注,如果該服務上遊沒有其他的負載均衡器的話,建議不要使用該參數,因為網際網路上的惡意掃描或其他動作就不會被記錄下來
option http-server-close #每次請求完畢後主動關閉http通道
option forwardfor except 127.0.0.0/8 #如果伺服器上的應用程式想記錄發起請求的用戶端的IP位址,需要在HAProxy上配置此選項, 這樣 HAProxy會把用戶端的IP資訊發送給伺服器,在HTTP 請求中添加"X-Forwarded-For"字段。啟用 X-Forwarded-For,在requests 頭部插入用戶端IP發送給後端的server,使後端server擷取到用戶端的真實IP。
option redispatch # 當使用了cookie時,haproxy将會将其請求的後端伺服器的serverID插入到cookie中,以保證會話的SESSION持久性;而此時,如果後端的伺服器宕掉 了, 但是用戶端的cookie是不會重新整理的,如果設定此參數,将會将客戶的請 求強制定向到另外一個後端server上,以保證服務的正常。
retries 3 # 定義連接配接後端伺服器的失敗重連次數,連接配接失敗次數超過此值後将會将對應後端伺服器标記為不可用
timeout http-request 10s #http請求逾時時間
timeout queue 1m #一個請求在隊列裡的逾時時間
timeout connect 10s #連接配接逾時
timeout client 1m #用戶端逾時
timeout server 1m #伺服器端逾時
timeout http-keep-alive 10s #設定http-keep-alive的逾時時間
timeout check 10s #檢測逾時
maxconn 3000 #每個程序可用的最大連接配接數
listen stats #定義一個listen子產品,用于狀态檢測
mode http #模式采用http
bind 0.0.0.0:8888 #綁定本機的位址及端口
stats enable #啟用狀态檢測功能
stats uri /haproxy-status #狀态檢測的URI
stats auth haproxy:123456 #通路檢測界面的使用者名和密碼
frontend main *:80 #frontend子產品的設定,定義了一個前端
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js #這裡定義了一個acl規則
use_backend static if url_static #如果比對到了acl,則通路後端的static子產品
default_backend my_webserver #如果沒有比對到acl,則将請求丢給預設的子產品
backend static #定義第一個後端子產品,static
balance roundrobin #負載均衡算法為輪詢
server static 127.0.0.1:80 check #後端伺服器位址
backend my_webserver #定第二個後端,my_wenserver
balance roundrobin #負載均衡算法
server web01 172.31.2.33:80 check inter 2000 fall 3 weight 30 #定義的多個後端
server web02 172.31.2.34:80 check inter 2000 fall 3 weight 30 #定義的多個後端
server web03 172.31.2.35:80 check inter 2000 fall 3 weight 30 #定義的多個後端
複制
2.健康檢查
Haproxy作為Loadblance,支援對backend的健康檢查,以保證在後端backend不能服務時,把從frontend進來的request配置設定至其他可以服務的backend,進而保證整體服務的可用性。
相關配置:
httpchk <method><uri><version>
option httpchk HEAD / HTTP/1.0
check:啟動健康檢測
inter:健康檢測時間間隔
rise:檢測服務可用的連接配接次數
fall:檢測服務不可用的連接配接次數
error-limit:往server寫資料連續失敗次數的上限,執行on-error的設定
observe<mode>:把正常服務過程作為健康檢測請求,即實時檢測
on-error<mode>:滿足error-limit後執行的操作(fastinter、fail-check、sudden-death、mark-down)。其中fastinter表示立即按照fastinter的檢測延時進行。fail-check表示改次error作為一次檢測;sudden-death表示模仿一次fatal,如果緊接着一次fail則server為down;mark-down表示直接把server設定為down狀态。
server web-node2 192.168.56.22:8080 check inter 2000 rise 30 fall 15
複制
3.檢測方式
1、通過監聽端口進行健康檢測
這種檢測方式,haproxy隻會去檢查server的端口,并不能保證服務真正可用。
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie serve02 check inter 500 rise 1 fall 2
複制
2、通過URI進行健康檢測
這種檢測方式,是用去GET後端server的web頁面,基本可以代表後端服務的可用性。
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk GET /index.html
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie serve02 check inter 500 rise 1 fall 2
複制
3、通過request擷取的頭部資訊進行比對進行健康檢測
這種檢測方式,是基于一些進階、精細的監測需求,通過對後端頭部通路的頭部資訊進行比對檢測。
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk HEAD /index.jsp HTTP/1.1\r\n\Host:\www.xxx.com
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie serve02 check inter 500 rise 1 fall 2
複制
Keepalived詳細介紹篇:
企業實戰(14)基于LVS-DR模式負載均衡+Keepalived高可用叢集實戰詳解
六、Haproxy負載均衡叢集實戰
準備4台Linux伺服器,兩台做Web伺服器,1台安裝HAProxy,1台做用戶端,實作如下功能:
用戶端通路Haproxy,Haproxy分發請求到後端Real Server;
開啟Haproxy監控頁面,及時檢視排程器狀态;
設定Haproxy為開機啟動;
使用4台虛拟機:
1台作為Haproxy排程器 2台作為Real Server 1台作為用戶端
環境介紹:
Haproxy排程伺服器:
192.168.2.130/24
真實伺服器1:
192.168.2.128/24
真實伺服器2:
192.168.2.129/24
用戶端:
192.168.2.132/24
注意:
如果在這之前有配置過其他負載均衡軟體,如:LVS、Nginx,則必須将網絡環境清理幹淨(清空LVS規則、關閉keepalived、删除VIP位址)。
一、後端真實伺服器配置
1.兩台後端伺服器128/129分别安裝Nginx
[root@localhost ~]# wget http://nginx.org/download/nginx-1.16.1.tar.gz
[root@localhost ~]# yum -y install gcc pcre-devel openssl-devel
[root@localhost ~]# useradd -s /sbin/nologin nginx //建立禁止登陸解釋器的使用者(為了安全)
[root@localhost ~]# id nginx
uid=1001(nginx) gid=1001(nginx) 組=1001(nginx)
[root@localhost ~]# tar -xf nginx-1.16.1.tar.gz
[root@localhost ~]# cd nginx-1.16.1
[root@localhost nginx-1.16.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module
--prefix=/usr/local/nginx //指定安裝路徑
--user=nginx //指定使用者
--group=nginx //指定組
--with-http_ssl_module //安裝ssl子產品,開啟其中的SSL加密功能(需要什麼子產品就安裝什麼子產品)
......
......
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
[root@localhost nginx-1.16.1]# make && make install //編譯并且安裝
......
'/usr/local/nginx/conf/scgi_params.default'
test -f '/usr/local/nginx/conf/nginx.conf' \
|| cp conf/nginx.conf '/usr/local/nginx/conf/nginx.conf'
cp conf/nginx.conf '/usr/local/nginx/conf/nginx.conf.default'
test -d '/usr/local/nginx/logs' \
|| mkdir -p '/usr/local/nginx/logs'
test -d '/usr/local/nginx/logs' \
|| mkdir -p '/usr/local/nginx/logs'
test -d '/usr/local/nginx/html' \
|| cp -R html '/usr/local/nginx'
test -d '/usr/local/nginx/logs' \
|| mkdir -p '/usr/local/nginx/logs'
make[1]: 離開目錄“/root/nginx-1.16.1”
[root@localhost ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module
[root@test2 ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module
複制
2.建立測試頁面
[root@localhost ~]# echo "I am 192.168.2.128" > /usr/local/nginx/html/index.html
[root@test2 ~]# echo "I am 192.168.2.129" > /usr/local/nginx/html/index.html
複制
3.啟動Nginx
[root@localhost nginx-1.16.1]# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
[root@localhost nginx-1.16.1]# netstat -antulp | grep :80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 6079/nginx: master
或者[root@localhost nginx-1.16.1]# netstat -antulp | grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 6079/nginx: master
複制
3.關閉防火牆與selinux
兩台後端伺服器都需要操作。
[root@test2 ~]# systmctl stop firewalld
[root@test2 ~]# setenforce 0
[root@test2 ~]# getenforce
Disabled
[root@test2 ~]# vim /etc/sysconfig/selinux //永久關閉selinux
SELINUX=disabled
複制
二、排程器部署Haproxy服務
1.安裝Haproxy軟體
[root@test3 ~]# yum -y install haproxy
複制
2.修改配置檔案
[root@test3 ~]# vim /etc/haproxy/haproxy.cfg
global ----> 以下為:全局設定
log 127.0.0.1 local2 ###[err warning info debug]
chroot /usr/local/haproxy //改變目前工作目錄
pidfile /var/run/haproxy.pid //haproxy的pid存放路徑
maxconn 4000 //最大連接配接數,預設4000
user haproxy //使用者haproxy運作啟動服務
group haproxy //使用者組為haproxy
daemon //建立1個程序進入deamon模式運作(放到背景)
......
defaults ------> 以下為:預設設定
mode http //預設的模式mode { tcp|http|health } tcp是4層,http是7層,health隻會傳回OK。
log global //采用全局定義的日志
option dontlognull //不記錄健康檢查的日志資訊
option httpclose //每次請求完畢後主動關閉http通道
option httplog //日志類别http日志格式
option forwardfor //後端伺服器可以從Http Header中獲得用戶端ip
option redispatch //serverid伺服器挂掉後強制定向到其他健康伺服器
timeout connect 10000 //如果backend沒有指定,預設為10s
timeout client 300000 //用戶端連接配接逾時
timeout server 300000 //伺服器連接配接逾時
maxconn 60000 //最大連接配接數
retries 3 //3次連接配接失敗就認為服務不可用,也可以通過後面設定
......
------> 以下為:叢集配置(手寫進去)
listen stats 0.0.0.0:1080 //監聽端口
stats refresh 30s //統計頁面自動重新整理時間
stats uri /stats //統計頁面url
stats realm Haproxy Manager //進入管理頁面檢視狀态資訊
stats auth admin:admin //統計頁面使用者名和密碼設定
#stats hide-version //隐藏統計頁面上HAProxy的版本資訊
listen websrv-rewrite 0.0.0.0:80
balance roundrobin //使用輪詢算法(rr)
server web1 192.168.2.100:80 check inter 2000 rise 2 fall 5
//每隔2000毫秒做一次健康檢查,允許失敗5次,連續失敗5次後從叢集剔除,重新通路2次後算成功,再添加入叢集.
server web2 192.168.2.200:80 check inter 2000 rise 2 fall 5
複制
3.啟動服務并設定開機自啟
[root@test3 ~]# systemctl start haproxy
[root@test3 ~]# systemctl enable haproxy
複制
三、用戶端驗證
用戶端配置與HAProxy相同網絡段的IP位址,并使用谷歌浏覽器通路http://192.168.2.130(或者用戶端curl http://192.168.2.130)測試排程器是否正常工作,用戶端通路http://192.168.2.130:1080/stats測試狀态監控頁面是否正常。
備注:
Queue隊列資料的資訊(目前隊列數量,最大值,隊列限制數量);
Session rate每秒會話率(目前值,最大值,限制數量);
Sessions總會話量(目前值,最大值,總量,Lbtot: total number of times a server was selected選中一台伺服器所用的總時間);
Bytes(入站、出站流量);
Denied(拒絕請求、拒絕回應);
Errors(錯誤請求、錯誤連接配接、錯誤回應);
Warnings(重新嘗試警告retry、重新連接配接redispatches);
Server(狀态、最後檢查的時間(多久前執行的最後一次檢查)、權重、備份伺服器數量、down機伺服器數量、down機時長)。