HAProxy深度解析:打造高效反向代理和負載均衡的利器

負載均衡:Load Balance,簡稱LB,是一種服務或基於硬體裝置等實現的高可用反向代理技術,負載均

衡將特定的業務(web服務、網路流量等)分擔給指定的一個或多個後端特定的伺服器或裝置,從而提高了

公司業務的併發處理能力、保證了業務的高可用性、方便了業務後期的水平動態擴充套件
為什麼使用負載均衡

Web伺服器的動態水平擴充套件

-->對使用者無感知

增加業務併發訪問及處理能力

-->解決單伺服器瓶頸問題

節約公網IP地址

-->降低IT支出成本

隱藏內部伺服器IP

-->提高內部伺服器安全性

配置簡單

-->固定格式的配置檔案

功能豐富

-->支援四層和七層,支援動態下線主機

效能較強

-->併發數萬甚至數十萬

負載均衡型別

四層:

LVS

LinuxVirtualServer
Nginx

1.9

版之後

HAProxy

HighAvailabilityProxy

七層:

HAProxy
Nginx

硬體:

F5

https:

/

/f5.com/zh

Netscaler

https:

/

/www.citrix.com.cn/products/citrix-adc/

Array

https:

/

/www.arraynetworks.com.cn/

深信服

http:

/

/www.sangfor.com.cn/

北京靈州

http:

/

/www.lingzhou.com.cn/cpzx/llfzjh/

應用場景

四層:Redis、Mysql、RabbitMQ、Memcache等

七層:Nginx、Tomcat、Apache、PHP、圖片、動靜分離、API等

HAProxy是法國開發者威利塔羅(Willy Tarreau) 在2000年使用C語言開發的一個開源軟體,是一款具

備高併發(一萬以上)、高效能的TCP和HTTP負載均衡器,支援基於cookie的永續性,自動故障切換,支

持正則表示式及web狀態統計,目前最新TLS版本為2.4

企業版網站:https://www.haproxy.com/
社群版網站:http://www.haproxy.org/

github:https://github.com/haproxy

HAproxy支援功能:

TCP 和 HTTP反向代理

SSL

/

TSL伺服器

可以針對HTTP請求新增cookie,進行路由後端伺服器

可平衡負載至後端伺服器,並支援持久連線

支援所有主伺服器故障切換至備用伺服器

支援專用埠實現監控服務

支援停止接受新連線請求,而不影響現有連線

可以在雙向新增,修改或刪除HTTP報文首部

響應報文壓縮

支援基於

pattern

實現連線請求的訪問控制

透過特定的URI為授權使用者提供詳細的狀態資訊

支援http反向代理

支援動態程式的反向代理

支援基於資料庫的反向代理

不具備的功能:

正向代理

--squid,nginx

快取代理

--varnish

web服務

--nginx、tengine、apache、php、tomcat

UDP

--目前不支援UDP協議

單機效能

--相比LVS效能較差

HAProxy 支援基於lua實現功能擴充套件,lua是一種小巧的指令碼語言,於1993年由巴西里約熱內盧天主教大學(Pontifical Catholic University of Rio de Janeiro)裡的一個研究小組開發,其設計目的是為了嵌入

應用程式中,從而為應用程式提供靈活的擴充套件和定製功能。
範例:CentOS 7 安裝haproxy
[root@centos7 ~]# yum install haproxy -y
範例:CentOS 8 安裝haproxy

[

root@centos8 ~

]

# dnf -y install haproxy

第三方安裝包

官方沒有提供rpm相關的包,可以透過第三方倉庫的rpm包

從第三方網站下載rpm包:https://pkgs.org/download/haproxy

範例:

[

root@centos8 ~

]

# wget http://www.nosuchhost.net/~cheese/fedora/packages/epel-7/x86_64/cheeserelease-7-1.noarch.rpm

[

root@centos8 ~

]

# rpm -ivh cheese-release-7-1.noarch.rpm

[

root@centos8 ~

]

# yum install haproxy

範例:利用第三方 yum 倉庫安裝

[

root@centos7 ~

]

# wget https://centos7.iuscommunity.org/ius-release.rpm

[

root@centos7 ~

]

# rpm -Uvh ius-release*rpm

[

root@centos7 ~

]

# yum -y install epel-release

[

root@centos7 ~

]

# rpm -Uvh ius-release*rpm

[

root@centos7 ~

]

# yum install haproxy

範例:下載rpm包離線安裝
#下載安裝lua庫對應的版本

[root

@centos7

~]

# wget
https:

/

/dl.iuscommunity.org/pub/ius/stable/CentOS/7

/x86_64/lua53u-libs-

5.3

.

4

-

1

.ius.centos7.x86_64.rpm

#安裝lua庫

[root

@centos7

~]

# yum -y install lua53u-libs-5.3.4-1.ius.centos7.x86_64.rpm
#下載haproxy

[root

@centos7

~]

# wget
https:

/

/dl.iuscommunity.org/pub/ius/stable/CentOS/7

/x86_64/haproxy18u-

1.8

.

20

-

1

.el7.ius.x86_64.rpm

#安裝haproxy

[root

@centos7

~]

# yum -y install haproxy18u-1.8.20-1.el7.ius.x86_64.rpm

編譯安裝HAproxy

# 依賴包

[root@centos8 ~]

# yum install gcc readline-devel

下載lua包

[root@centos8 ~]

# wget http://www.lua.org/ftp/lua-5.3.5.tar.gz

[root@centos8 ~]

# tar xf lua-5.3.5.tar.gz -C /usr/local/src/

[root@centos8 ~]

# cd /usr/local/src/lua-5.3.5/

[root@centos8 ~]

# make linux test

# 檢視lua安裝的版本

[root@centos8 ~]

# /usr/local/src/lua-5.3.5/src/lua -v
# 依賴包

[root@centos8 ~]

# yum -y install gcc openssl-devel pcre-devel systemd-devel readline-devel

[root@centos8 ~]

# tar xf haproxy-2.1.3.tar.gz -C /usr/local/src/

[root@centos8 ~]

# cd /usr/local/src/haproxy-2.1.3/

[root@centos8 ~]

# make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.3.5/src/ LUA_LIB=/usr/local/src/lua-5.3.5/src/

[root@centos8 ~]

# make install PREFIX=/apps/haproxy

[root@centos8 ~]

# ln -s /apps/haproxy/sbin/haproxy /usr/sbin/

# 檢視haproxy安裝的版本

[root@centos8 ~]

# haproxy -v

啟動檔案
[root@centos8 ~]# vim /usr/lib/systemd/system/haproxy.service
[Unit]
Description

=HAProxy Load Balancer

After

=syslog.target network.target

[Service]
ExecStartPre

=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q

ExecStart

=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid

ExecReload

=/bin/kill -USR2

$MAINPID
LimitNOFILE

=

100000

[Install]
WantedBy

=multi-user.target

重新載入

[

root@centos8 ~

]

# systemctl daemon-reload

[

root@centos8 ~

]

# systemctl start haproxy

# 建立兩個資料夾

[

root@centos8 ~

]

# mkdir /etc/haproxy

[

root@centos8 ~

]

# mkdir /var/lib/haproxy

配置檔案

[root@centos8 ~]

# vim /etc/haproxy/haproxy.cfg

global

maxconn 100000

chroot

/apps/haproxy

stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin

uid 99

gid 99

user haproxy

group haproxy

daemon

#nbproc 4
#cpu-map 1 0
#cpu-map 2 1
#cpu-map 3 2
#cpu-map 4 3

pidfile /var/lib/haproxy/haproxy.pid

log

127.0.0.1 local2 info
defaults

option http-keep-alive

option forwardfor

maxconn 100000

mode http

timeout

connect 300000ms

timeout

client 300000ms

timeout

server 300000ms
listen stats

mode http

bind

0.0.0.0:9999

stats

enable
log

global

stats uri /status

stats auth haadmin:123456

listen web_port

bind

172.31.0.28:80

mode http

log

global

#server web1 127.0.0.1:8080 check inter 3000 fall 2 rise 5

server 172.31.0.17 172.31.0.17:80 check inter 3000 fall 2 rise 5

# 這是後端的web伺服器,必須要有

server 172.31.0.27 172.31.0.27:80 check inter 3000 fall 2 rise 5

# 這是後端的web伺服器,必須要有

haproxy.cfg檔案中定義了chroot、pidfile、user、group等引數,如果系統沒有相應的資源會導致

haproxy無法啟動,具體參考日誌檔案 /var/log/messages

[root@centos8 ~]# journalctl -xe
Jun

2205

:

08

:

24

centos8.longxuan.vip haproxy[

10959

]: [ALERT]

172

/

050824

(

10959

) : Cannot

openconfigurationfile

/directory /etc/haproxy/haproxy.cfg : No such

fileor

direct

Jun

2205

:

08

:

24

centos8.longxuan.vip systemd[

1

]: haproxy.service: Control

process

exited, code=exited status=

1

Jun

2205

:

08

:

24

centos8.longxuan.vip systemd[

1

]: haproxy.service: Failed

with

result

'exit

-code'.
Jun

2205

:

12

:

13

centos8.longxuan.vip systemd[

1

]: Starting HAProxy Load Balancer...

Jun

2205

:

12

:

13

centos8.longxuan.vip haproxy[

10974

]: [ALERT]

172

/

051213

(

10974

) : parsing [/etc/haproxy/haproxy.cfg:

7

] : cannot find user id

for'haproxy

' (

0

:Success)

Jun

2205

:

12

:

13

centos8.longxuan.vip haproxy[

10974

]: [ALERT]

172

/

051213

(

10974

) : parsing [/etc/haproxy/haproxy.cfg:

8

] : cannot find

group

id

for'haproxy

' (

0

:Success)

Jun

2205

:

12

:

13

centos8.longxuan.vip haproxy[

10974

]: [ALERT]

172

/

051213

(

10974

) :

Error

(s) found

inconfigurationfile

: /etc/haproxy/haproxy.cfg

Jun

2205

:

12

:

13

centos8.longxuan.vip haproxy[

10974

]: [ALERT]

172

/

051213

(

10974

) : Fatal errors found

inconfiguration

.

檢視haproxy的狀態頁面

瀏覽器訪問: http://haproxy-server:9999/status

基礎配置詳解

官方文件:

http://cbonte.github.io/haproxy-dconv/

# 帶版本的(2.1版本)

http://cbonte.github.io/haproxy-dconv/2.1/configuration.html

HAProxy 的配置檔案haproxy.cfg由兩大部分組成,分別是global和proxies部分
global:全域性配置段

程序及安全配置相關的引數

效能調整相關引數

Debug

引數

proxies:代理配置段

defaults:為frontend, backend,

listen

提供預設配置

frontend:前端,相當於nginx中的server {}

backend:後端,相當於nginx中的upstream {}

listen

:同時擁有前端和後端配置,配置簡單,生產推薦使用

global 配置引數說明

官方文件:http:

//

cbonte.github.io/haproxy-dconv/

2.4

/configuration.html

#3

chroot#鎖定執行目錄

deamon

#以守護程序執行

stats

socket

/var/lib/haproxy/haproxy.sock mode

600

level admin process

1
#socket檔案

user, group, uid, gid

#執行haproxy的使用者身份

nbproc n

#開啟的haproxy worker 程序數,預設程序數是一個
#nbthread 1 #和多程序 nbproc配置互斥(版本有關,CentOS8的haproxy1.8無此問題),指定每

個haproxy程序開啟的執行緒數,預設為每個程序一個執行緒

#如果同時啟用nbproc和nbthread 會出現以下日誌的錯誤,無法啟動服務

Apr

714

:

46

:

23

haproxy haproxy: [ALERT] 097/

144623

(

1454

) : config : cannot

enable multiple processes

if

multiple threads are configured. Please

use

either

nbproc

or

nbthread but

not

both.

cpu-

map10#繫結haproxy worker 程序至指定CPU,將第1個work程序繫結至0號CPU

cpu-

map21#繫結haproxy worker 程序至指定CPU,將第2個work程序繫結至1號CPU

maxconn n

#每個haproxy程序的最大併發連線數

maxsslconn n

#每個haproxy程序ssl最大連線數,用於haproxy配置了證書的場景下

maxconnrate n

#每個程序每秒建立的最大連線數量

spread-checks n

#後端server狀態check隨機提前或延遲百分比時間,建議2-5(20%-50%)之間,預設

0

pidfile

#指定pid檔案路徑
log127.0

.

0

.

1

local2 info

#定義全域性的syslog伺服器;日誌伺服器需要開啟UDP協議,最多可以定

義兩個

多程序和執行緒

範例:多程序和socket檔案

[

root@centos7 ~

]

# vim /etc/haproxy/haproxy.cfg
global

maxconn

100000

chroot /apps/haproxy

stats socket /

var

/lib/haproxy/haproxy.sock1 mode

600

level admin process

1

stats socket /

var

/lib/haproxy/haproxy.sock2 mode

600

level admin process

2

uid

99

gid

99

daemon

nbproc

2

[

root@centos7 ~

]

# systemctl restart haproxy

[

root@centos7 ~

]

# pstree -p |grep haproxy

|-haproxy(

2688

)-+-haproxy(

2690

)

| `-haproxy(

2691

)
[

root@centos7 ~

]

# ll /var/lib/haproxy/

total

4

-rw-r--r--

1

root root

5

Mar

3110

:

49

haproxy.pid

srw-------

1

root root

0

Mar

3110

:

49

haproxy.sock1

srw-------

1

root root

0

Mar

3110

:

49

haproxy.sock2

HAProxy日誌配置

HAproxy本身不記錄客戶端的訪問日誌.此外為減少伺服器負載,一般生產中HAProxy不記錄日誌.

也可以配置HAProxy利用rsyslog服務記錄日誌到指定日誌檔案中

HAProxy配置

[root@centos7 ~]

# vim /etc/haproxy/haproxy.cfg
#在global配置項定義:
log127.0

.

0

.

1local

{

1

-

7

} info

#基於syslog記錄日誌到指定裝置,級別有(err、warning、

info、debug)

listen

web_port

bind127.0

.

0

.

1

:

80

mode http

log

global

#開啟當前web_port的日誌功能,預設不記錄日

server web1

127.0

.

0

.

1

:

8080

check inter

3000

fall

2

rise

5

[root@centos7 ~]

# systemctl restart haproxy

Rsyslog配置(CentOS7版本的寫法)生產不推薦haproxy記錄日誌,這樣會加大haproxy負載

[root@centos7 ~]

# vim /etc/rsyslog.conf

$ModLoad imudp

$UDPServerRun

514

......

local3.*

/var/l

og/haproxy.log

......

[root@centos7 ~]

# systemctl restart rsyslog

重啟syslog服務並訪問app頁面,然後驗證是否生成日誌

[

root@centos8 ~

]

# tail -f /var/log/haproxy.log

Jun

2219

:

01

:

09

localhost haproxy[

11406

]: Connect

from172.31.0.29

:

50626

to

172.31.0.28

:

80

(web_port/HTTP)

Proxies配置

官方文件:http://cbonte.github.io/haproxy-dconv/2.1/configuration.html

#4

defaults [<name>]

#預設配置項,針對以下的frontend、backend和listen生效,可以多個name也可

以沒有name

frontend <name>

#前端servername,類似於Nginx的一個虛擬主機 server和LVS服務叢集。

backend <name>

#後端伺服器組,等於nginx的upstream和LVS中的RS伺服器

listen <name>

#將frontend和backend合併在一起配置,相對於frontend和backend配置更簡

潔,生產常用

注意:name欄位只能使用大小寫字母,數字,‘-’(dash),'_‘(underscore),'.' (dot)和 ':'(colon),並且嚴格區分大小寫

Proxies配置-defaults

option redispatch

#當server Id對應的伺服器掛掉後,強制定向到其他健康的伺服器,重新派

option abortonclose

#當伺服器負載很高時,自動結束掉當前佇列處理比較久的連線,針對業務情

況選擇開啟

option http-keep-alive

#開啟與客戶端的會話保持

option forwardfor

#透傳客戶端真實IP至後端web伺服器

mode http|tcp

#設定預設工作型別,使用TCP伺服器效能更好,減少壓力
timeout

http-keep-alive 120s

#session 會話保持超時時間,此時間段內會轉發到相同的後端服務

timeout

connect 120s

#客戶端請求從haproxy到後端server最長連線等待時間(TCP連線之前),

預設單位ms

timeout

server 600s

#客戶端請求從haproxy到後端服務端的請求處理超時時長(TCP連線之後),

預設單位ms,如果超時,會出現502錯誤,此值建議設定較大些,訪止502錯誤

timeout

client 600s

#設定haproxy與客戶端的最長非活動時間,預設單位ms,建議和timeout

server相同

timeout

check 5s

#對後端伺服器的預設檢測超時時間

default-server inter 1000 weight 3

#指定後端伺服器的預設設定

Proxies配置-listen 簡化配置

使用listen替換 frontend和backend的配置方式,可以簡化設定,通常只用於TCP協議的應用
#官網業務訪問入口
listen

WEB_PORT_8

0
bind10.0

.

0

.

7

:

80

mode http

option forwardfor

server web1

172.31

.

0

.

17

:

8080

check inter

3000

fall

3

rise

5

server web2

172.31

.

0

.

27

:

8080

check inter

3000

fall

3

rise

5

Proxies配置-frontend

bind: #指定HAProxy的監聽地址,可以是IPV4或IPV6,可以同時監聽多個IP或埠,可同時用於

listen欄位中

#格式:
bind

[<

address>]:<port_range>

[, ...] [param*]

#注意:如果需要繫結在非本機的IP,需要開啟核心引數:net.ipv4.ip_nonlocal_bind=1
backlog

<

backlog> #針對所有server配置,當前端伺服器的連線數達到上限後的後援佇列長度,注意:不支援backend

範例:
listen

http_proxy

#監聽http的多個IP的多個埠和sock檔案
bind

:

80

,:

443

,:

8801

-

8810
bind171.31

.

0

.

1

:

10080

,

172.31

.

0

.

1

:

10443
bind

/var/run/ssl-frontend.sock user root mode

600accept

-proxy

listen

http_https_proxy

#https監聽
bind

:

80
bind

:

443

ssl crt /etc/haproxy/site.pem

#公鑰和私鑰公共檔案

listen

http_https_proxy_explicit

#監聽ipv6、ipv4和unix sock檔案
bind

ipv6@:

80
bind

ipv4@public_ssl:

443

ssl crt /etc/haproxy/site.pem

bind

[email protected] user root mode

600accept

-proxy

listen

external_bind_app1

#監聽file descriptor
bind"fd@${FD_APP1}"

生產示例:

frontend magedu_web_port

#可以採用後面形式命名:業務-服務-埠號
bind

:80,:8080

bind

172.31.0.7:10080,:8801-8810,172.31.0.17:9001-9010

mode http|tcp

#指定負載協議型別

use_backend <backend_name>

#呼叫的後端伺服器組名稱

Proxies配置-backend

定義一組後端伺服器,backend伺服器將被frontend進行呼叫。

注意: backend 的名稱必須唯一,並且必須在listen或frontend中事先定義才可以使用,否則服務無法啟動

mode http|tcp

#指定負載協議型別,和對應的frontend必須一致
option#配置選項

server

#定義後端real server,必須指定IP和埠

注意:option後面加 httpchk,smtpchk,mysql-check,pgsql-check,ssl-hello-chk方法,可用於實現更多應用層檢測功能。
server 配置
#針對一個server配置

check

#對指定real進行健康狀態檢查,如果不加此設定,預設不開啟檢查,只有check後面沒有其它配置也可以啟用檢查功能
#預設對相應的後端伺服器IP和埠,利用TCP連線進行週期性健康性檢查,注意必須指定端口才能實現健康性檢查

addr <IP>

#可指定的健康狀態監測IP,可以是專門的資料網段,減少業務網路的流量

port <num>

#指定的健康狀態監測埠

inter <num>

#健康狀態檢查間隔時間,預設2000 ms

fall <num>

#後端伺服器從線上轉為線下的檢查的連續失效次數,預設為3

rise <num>

#後端伺服器從下線恢復上線的檢查的連續有效次數,預設為2

weight <weight>

#預設為1,最大值為256,0(狀態為藍色)表示不參與負載均衡,但仍接受持久連

backup

#將後端伺服器標記為備份狀態,只在所有非備份主機down機時提供服務,類似

Sorry Server

disabled

#將後端伺服器標記為不可用狀態,即維護狀態,除了持久模式,將不再接受連線,狀態為深黃色,優雅下線,不再接受新使用者的請求

redirect prefix http://www.baidu.com/

#將請求臨時(302)重定向至其它URL,只適用於http模式

redir http://www.baidu.com

#將請求臨時(302)重定向至其它URL,只適用於http模式

maxconn <maxconn>

#當前後端server的最大併發連線數

frontend+backend 配置例項

frontend longxuan-

test

-http

bind :

80

,:

8080

mode tcp

use_backend longxuan-

test

-http-nodes
backend longxuan-

test

-http-nodes

mode tcp

default

-server inter

1000

weight

6

server web1

172.31.0.17

:

80

weight

2

check addr

172.31.0.117

port

8080

server web1

172.31.0.27

:

80

check

範例2:
#官網業務訪問入口
frontendWEB_PORT_80
bind10.0.0.7:80
modehttp
use_backendweb_prot_http_nodes

backendweb_prot_http_nodes
modehttp
optionforwardfor
server10.0.0.1710.0.0.17:8080checkinter3000 fall3rise5
server10.0.0.2710.0.0.27:8080checkinter3000 fall3rise5

使用子配置檔案儲存配置

當業務眾多時,將所有配置都放在一個配置檔案中,會造成維護困難。可以考慮按業務分類,將配置信

息拆分,放在不同的子配置檔案中,從而達到方便維護的目的。

注意: 子配置檔案的檔案字尾必須為.cfg

#建立子配置目錄

[root

@centos7

~]

# mkdir /etc/haproxy/conf.d/
#建立子配置檔案,注意:必須為cfg字尾非.開頭的配置檔案

[root

@centos7

~]

# vim /etc/haproxy/conf.d/test.cfg

listen WEB_PORT_80

bind

172.31

.

0.7:80

mode http

balance roundrobin

server web1

172.31

.

0.17:80

check inter

3000

fall

2

rise

5

server web2

172.31

.

0.27:80

check inter

3000

fall

2

rise

5

#新增子配置目錄到unit檔案中

[root

@centos7

~]

# vim /lib/systemd/system/haproxy.service

[Unit]

Description=HAProxy Load Balancer

After=syslog.target network.target

[Service]

#修改下面兩行

ExecStartPre=

/usr/sbin/haproxy -f /etc/haproxy/haproxy

.cfg -f /etc/haproxy/conf.d/ -c -q

ExecStart=

/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy

.cfg -f /etc/haproxy/conf.d/ -p /var/lib/haproxy/haproxy.pid

ExecReload=

/bin/kill

-USR2

$MAINPID

[Install]

WantedBy=multi-user.target

#重新載入並啟動

[root

@centos7

~]

# systemctl daemon-reload

[root

@centos7

~]

# systemctl restart haproxy

連結:https://www.cnblogs.com/xuanlv-0413/p/15037087.html
(版權歸原作者所有,侵刪)


相關文章