35.第29章 HAProxy負載均衡


一.HAProxy調度算法

1.靜態算法

靜態算法:按照事先定義好的規則輪詢公平調度,不關⼼后端服務器的當前負載、鏈接數和響應速度等,且⽆法實時修改權重,只能靠重啟HAProxy⽣效。

1.1 static-rr

static-rr:基於權重的輪詢調度,不⽀持權重的運⾏時調整及后端服務器慢啟動,其后端主機數量沒有限制

1.2 first

first:根據服務器在列表中的位置,⾃上⽽下進⾏調度,但是其只會當第⼀台服務器的連接數達到上限,新請求才會分配給下⼀台服務,因此會忽略服務器的權重設置。

2.動態算法

動態算法:基於后端服務器 狀態進⾏調度適當調整,⽐如優先調度⾄當前負載較低的服務器,且權重可以在haproxy運⾏時動態調整⽆需重啟。

2.1 roundrobin

roundrobin:基於權重的輪詢動態調度算法,⽀持權重的運⾏時調整,不完全等於lvs中的rr輪訓模式,HAProxy中的roundrobin⽀持慢啟動(新加的服務器會逐漸增加轉發數),其每個后端backend中最多⽀持4095個real server,roundrobin為默認調度算法,且⽀持對real server權重動態調整。

2.2 leastconn

leastconn加權的最少連接的動態,⽀持權重的運⾏時調整和慢啟動,即當前后端服務器連接最少的優先調度(新客戶端連接),⽐較適合⻓連接的場景使⽤,⽐如MySQL等場景。

3.其他算法

其他部分算法即可作為靜態算法,⼜可以通過選項成為動態算法

3.1 source

源地址hash,基於⽤戶源地址hash並將請求轉發到后端服務器,默認為靜態即取模⽅式,但是可以通過hash-type⽀持的選項更改,后續同⼀個源地址請求將被轉發⾄同⼀個后端web服務器,⽐較適⽤於session保持/緩存業務等場景。
源地址有兩種轉發客戶端請求到后端服務器的服務器選取計算⽅式,分別是取模法和⼀致性hash

3.1.1 map-base取模法

map-based:取模法,基於服務器總權重的hash數組取模,該hash是靜態的即不⽀持在線調整權重,不⽀持慢啟動,其對后端服務器調度均衡,缺點是當服務器的總權重發⽣變化時,即有服務器上線或下線,都會因權重發⽣變化⽽導致調度結果整體改變。
所謂取模運算,就是計算兩個數相除之后的余數,10%7=3,7%4=3,基於權重取模:(2^32-1)%(1+1+2),公式為,hash(o)mod n,即a mod b=c,表明a除以b余數為c。

3.1.2 ⼀致性hash

⼀致性哈希,該hash是動態的,⽀持在線調整權重,⽀持慢啟動,優點在於當服務器的總權重發⽣變化時,對調度結果影響是局部的,不會引起⼤的變動。

3.2 uri

基於對⽤戶請求的uri做hash並將請求轉發到后端指定服務器,也可以通過map-based和consistent定義使⽤取模法還是⼀致性hash。

3.3 url_param

url_param對⽤戶請求的url中的 params 部分中的參數name作hash計算,並由服務器總權重相除以后派發⾄某挑出的服務器;通常⽤於追蹤⽤戶,以確保來⾃同⼀個⽤戶的請求始終發往同⼀個real server

3.4 hdr

針對⽤戶每個http頭部(header)請求中的指定信息做hash,此處由name 指定的http⾸部將會被取出並做hash計算,然后由服務器總權重相除以后派發⾄某挑出的服務器,假如⽆有效的值,則會使⽤默認的輪詢調度。

3.5 rdp-cookie

rdp-cookie使⽤客戶端cookie保持會話,可以實現對windows遠程桌⾯的負載等

3.6 random

在1.9版本開始增加⼀個叫做random的負載平衡算法,其基於⼀個隨機數作為⼀致性hash的key,隨機負載平衡對於⼤型服務器場或經常添加或刪除服務器⾮常有⽤。

算法總結:

static-rr--------->tcp/http 靜態
first------------->tcp/http 靜態
roundrobin-------->tcp/http 動態
leastconn--------->tcp/http 動態
random------------>tcp/http 動態
source------------>tcp/http
Uri--------------->http
url_param--------->http 取決於hash_type是否
consistent
hdr--------------->http
rdp-cookie-------->tcp

各算法使⽤場景:

first #使⽤較少

static-rr #做了session共享的web集群
roundrobin
random

leastconn #數據庫
source #基於客戶端公⽹IP的會話保持

Uri--------------->http #緩存服務器,CDN服務商,藍汛、百度、阿⾥雲、騰訊
url_param--------->http

hdr #基於客戶端請求報⽂頭部做下⼀步處理

rdp-cookie #很少使⽤

二.HAProxy一鍵編譯安裝

[root@centos7 ~]# cat install_haproxy.sh
#!/bin/bash
#
#******************************************************************************
#Author:        zhanghui
#QQ:            19661891
#Date:          2021-09-03
#FileName:      install_haproxy.sh
#URL:           www.cnblogs.com/neteagles
#Description:   install_haproxy for centos 7/8 & ubuntu 18.04/20.04
#Copyright (C): 2021 All rights reserved
#******************************************************************************
SRC_DIR=/usr/local/src
COLOR="echo -e \\033[01;31m"
END='\033[0m'
CPUS=`lscpu |awk '/^CPU\(s\)/{print $2}'`

LUA_FILE=lua-5.4.3.tar.gz
HAPROXY_FILE=haproxy-2.4.3.tar.gz
HAPROXY_INSTALL_DIR=/apps/haproxy

STATS_AUTH_USER=admin
STATS_AUTH_PASSWORD=123456

NET_NAME=`ip a |awk -F"[: ]" '/^2/{print $3}'`
IP=`ip addr show ${NET_NAME}| awk -F" +|/" '/global/{print $3}'`

os(){
    if grep -Eqi "CentOS" /etc/issue || grep -Eq "CentOS" /etc/*-release;then
        rpm -q redhat-lsb-core &> /dev/null || { ${COLOR}"安裝lsb_release工具"${END};yum -y install  redhat-lsb-core &> /dev/null; }
    fi
    OS_ID=`lsb_release -is`
}

check_file (){
    cd ${SRC_DIR}
    ${COLOR}'檢查HAPROXY相關源碼包'${END}
    if [ ! -e ${LUA_FILE} ];then
        ${COLOR}"缺少${LUA_FILE}文件"${END}
        exit
    elif [ ! -e ${HAPROXY_FILE} ];then
        ${COLOR}"缺少${HAPROXY_FILE}文件"${END}
        exit
    else
        ${COLOR}"相關文件已准備好"${END}
    fi
}

install_haproxy(){
    [ -d ${HAPROXY_INSTALL_DIR} ] && { ${COLOR}"haproxy已存在,安裝失敗"${END};exit; }
    ${COLOR}"開始安裝HAPROXY"${END}
    ${COLOR}"開始安裝HAPROXY依賴包"${END}
    if [ ${OS_ID} == "CentOS" ] &> /dev/null;then
        yum -y install gcc make gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel libtermcap-devel ncurses-devel libevent-devel readline-devel &> /dev/null
    else
        apt update &> /dev/null;apt -y install gcc make openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev  libreadline-dev libsystemd-dev &> /dev/null
    fi
    tar xf ${LUA_FILE}
    LUA_DIR=`echo ${LUA_FILE} | sed -nr 's/^(.*[0-9]).*/\1/p'`
    cd ${LUA_DIR}
    make all test
    cd ${SRC_DIR}
    tar xf ${HAPROXY_FILE}
    HAPROXY_DIR=`echo ${HAPROXY_FILE} | sed -nr 's/^(.*[0-9]).*/\1/p'`
    cd ${HAPROXY_DIR}
    make -j ${CPUS} ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_CPU_AFFINITY=1 USE_LUA=1 LUA_INC=/usr/local/src/${LUA_DIR}/src/ LUA_LIB=/usr/local/src/${LUA_DIR}/src/ PREFIX=${HAPROXY_INSTALL_DIR}
    make install PREFIX=${HAPROXY_INSTALL_DIR}
    [ $? -eq 0 ] && $COLOR"HAPROXY編譯安裝成功"$END ||  { $COLOR"HAPROXY編譯安裝失敗,退出!"$END;exit; }
    cat > /lib/systemd/system/haproxy.service <<-EOF
[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

[Install]
WantedBy=multi-user.target
EOF
    [ -L /usr/sbin/haproxy ] || ln -s ../../apps/haproxy/sbin/haproxy /usr/sbin/ &> /dev/null
    [ -d /etc/haproxy ] || mkdir /etc/haproxy &> /dev/null  
    [ -d /var/lib/haproxy/ ] || mkdir -p /var/lib/haproxy/ &> /dev/null
    cat > /etc/haproxy/haproxy.cfg <<-EOF
global
maxconn 100000
chroot /apps/haproxy
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
uid 99
gid 99
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 local3 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 /haproxy-status
    stats auth ${STATS_AUTH_USER}:${STATS_AUTH_PASSWORD}
EOF
    echo "PATH=${HAPROXY_INSTALL_DIR}/sbin:${PATH}" > /etc/profile.d/haproxy.sh
    systemctl daemon-reload
    systemctl enable --now haproxy &> /dev/null
    systemctl is-active haproxy &> /dev/null ||  { ${COLOR}"HAPROXY 啟動失敗,退出!"${END} ; exit; }
    ${COLOR}"HAPROXY安裝完成"${END} && ${COLOR}"HAPROXY狀態頁地址: http://${IP}:9999/haproxy-status,用戶名:admin,密碼:123456"${END}
}

main(){
    os
    check_file
    install_haproxy
}

main


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM