?1. 總結負載均衡常見的算法
輪詢 (Round Robin):按順序將請求依次分配給后端服務器,適合服務器性能相近的場景。
加權輪詢 (Weighted Round Robin):在輪詢的基礎上,根據服務器的權重分配請求。
隨機 (Random):隨機選擇一臺服務器處理請求,簡單但不考慮負載。
加權隨機 (Weighted Random):在隨機的基礎上,根據服務器的權重進行隨機選擇。
源IP哈希 (Source IP Hash):根據請求的源IP地址進行哈希計算,將請求分配給特定的服務器。
最少連接算法(Least Connections)最少連接算法是一種動態調整的負載均衡算法。其思路是盡可能將請求分配到當前空閑連接數最少的后端服務器,以達到負載均衡的效果。在實現過程中,通常需要定期檢測每個服務器的連接數并進行動態調整。
? ? 2. 使用keepalived做nginx和haproxy高可用
#安裝
sudo apt-get update
sudo apt-get install keepalived
sudo apt-get install nginx#編輯配置文件
sudo vim /etc/keepalived/keepalived.conf?
global_defs {
? router_id nginx
}# nginx檢測腳本
vrrp_script check_nginx {
? script "/etc/keepalived/check_nginx.sh"
? interval 2
? weight 50
}vrrp_instance VI_1 {
? ? # 實例初始化狀態 (MASTER or BACKUP)
? ? state MASTER ? ? ? ? ? ?
? ? # vrrp監聽的網卡設備
? ? interface ens33 ? ?
? ? # 虛擬路由ID(0-255),可用過tcpdump vrrp查看(vrid)
? ? virtual_router_id 62 ? ?
? ? # 優先級, 優先級高的競選為master
? ? priority 151 ? ?
? ? # vrrp廣播間隔(單位:秒,可用小數點)
? ? advert_int 1 ??
? ? # 非搶占模式,只適用于BACKUP state,允許一個priority更低的節點作為master
? ? # (官方)NOTE: For this to work, the initial state must not be MASTER.
? ? nopreempt?? ??? ??? ?
? ? # vrrp單播,源IP
? ? unicast_src_ip 172.25.254.131
? ? # vrrp單播,對端IP
? ? unicast_peer {
? ? ? ? 172.25.254.132
? ? }
? ? # 用于節點間的通訊認證,需要主備設置一致
? ? authentication { ? ? ? ?
? ? ? ? auth_type PASS
? ? ? ? auth_pass 1111
? ? }
? ? # 虛擬IP
? ? virtual_ipaddress {
? ? ? ? 172.25.254.130 ? ? ?
? ? }
? ? # 服務檢測腳本
? ? track_script {
? ? ? ? check_nginx
? ? }
}
?
#服務器編輯配置文件
sudo vim /etc/keepalived/keepalived.conf?
global_defs {
? router_id nginx
}# nginx檢測腳本
vrrp_script check_nginx {
? script "/etc/keepalived/check_nginx.sh"
? interval 2
? weight 50
}vrrp_instance VI_1 {
? ? # 實例初始化狀態 (MASTER or BACKUP)
? ? state BACKUP ? ? ? ? ? ?
? ? # vrrp監聽的網卡設備
? ? interface ens33 ? ?
? ? # 虛擬路由ID(0-255),可用過tcpdump vrrp查看(vrid)
? ? virtual_router_id 62 ? ?
? ? # 優先級, 優先級高的競選為master
? ? priority 150 ? ?
? ? # vrrp廣播間隔(單位:秒,可用小數點)
? ? advert_int 1 ??
? ? # 非搶占模式,只適用于BACKUP state,允許一個priority更低的節點作為master
? ? # NOTE: For this to work, the initial state must not be MASTER.
? ? nopreempt?? ??? ??? ?
? ? # vrrp單播,源IP
? ? unicast_src_ip 172.25.254.132
? ? # vrrp單播,對端IP
? ? unicast_peer {
? ? ? ? 172.25.254.131
? ? }
? ? # 用于節點間的通訊認證,需要主備設置一致
? ? authentication { ? ? ? ?
? ? ? ? auth_type PASS
? ? ? ? auth_pass 1111
? ? }
? ? # 虛擬IP
? ? virtual_ipaddress {
? ? ? ? 172.25.254.130 ? ? ?
? ? }
? ? # 服務檢測腳本
? ? track_script {
? ? ? ? check_nginx
? ? }
}
?
兩臺服務器中都生成如下nginx檢測腳本
sudo vim /etc/keepalived/check_nginx.sh
#!/bin/sh
if [ -z "`/usr/bin/pidof nginx`" ]; then
? systemctl stop keepalived
? exit 1
fi
#添加權限
sudo chmod +x /etc/keepalived/check_nginx.sh
啟動服務
啟動nginx,并檢查服務狀態
sudo systemctl start nginx
systemctl status nginx● nginx.service - A high performance web server and a reverse proxy server
? ? ?Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
? ? ?Active: active (running) since Tue 2024-05-07 07:22:43 UTC; 37s ago
? ? ? ?Docs: man:nginx(8)
? ? Process: 205677 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
? ? Process: 205678 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
? ?Main PID: 205679 (nginx)
? ? ? Tasks: 3 (limit: 4515)
? ? ?Memory: 3.3M
? ? ? ? CPU: 52ms
? ? ?CGroup: /system.slice/nginx.service
? ? ? ? ? ? ?├─205679 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
? ? ? ? ? ? ?├─205680 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
? ? ? ? ? ? ?└─205681 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""May 07 07:22:43 svr1 systemd[1]: Starting A high performance web server and a reverse proxy server...
May 07 07:22:43 svr1 systemd[1]: Started A high performance web server and a reverse proxy server.
啟動keepalived,并檢查服務狀態
sudo systemctl start keepalived
systemctl status keepalived● keepalived.service - Keepalive Daemon (LVS and VRRP)
? ? ?Loaded: loaded (/lib/systemd/system/keepalived.service; enabled; vendor preset: enabled)
? ? ?Active: active (running) since Tue 2024-05-07 07:25:20 UTC; 18s ago
? ?Main PID: 205688 (keepalived)
? ? ? Tasks: 2 (limit: 4515)
? ? ?Memory: 2.0M
? ? ? ? CPU: 265ms
? ? ?CGroup: /system.slice/keepalived.service
? ? ? ? ? ? ?├─205688 /usr/sbin/keepalived --dont-fork
? ? ? ? ? ? ?└─205689 /usr/sbin/keepalived --dont-forkMay 07 07:25:20 svr1 Keepalived[205688]: Starting VRRP child process, pid=205689
May 07 07:25:20 svr1 systemd[1]: keepalived.service: Got notification message from PID 205689, but reception only permitted for main PID 205688
May 07 07:25:20 svr1 Keepalived_vrrp[205689]: WARNING - default user 'keepalived_script' for script execution does not exist - please create.
May 07 07:25:20 svr1 Keepalived_vrrp[205689]: SECURITY VIOLATION - scripts are being executed but script_security not enabled.
May 07 07:25:20 svr1 Keepalived[205688]: Startup complete
May 07 07:25:20 svr1 systemd[1]: Started Keepalive Daemon (LVS and VRRP).
May 07 07:25:20 svr1 Keepalived_vrrp[205689]: (VI_1) Entering BACKUP STATE (init)
May 07 07:25:20 svr1 Keepalived_vrrp[205689]: VRRP_Script(check_nginx) succeeded
May 07 07:25:20 svr1 Keepalived_vrrp[205689]: (VI_1) Changing effective priority from 101 to 151
May 07 07:25:24 svr1 Keepalived_vrrp[205689]: (VI_1) Entering MASTER STATE
啟動Keepalived以后,主節點中查看是否綁定了配置中的VIP
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
? ? link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
? ? inet 127.0.0.1/8 scope host lo
? ? ? ?valid_lft forever preferred_lft forever
? ? inet6 ::1/128 scope host?
? ? ? ?valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
? ? link/ether 00:0c:29:a1:d7:ea brd ff:ff:ff:ff:ff:ff
? ? altname enp2s1
? ? inet 172.25.254.131/24 brd 172.25.254.255 scope global ens33
? ? ? ?valid_lft forever preferred_lft forever
? ? inet 172.25.254.130/32 scope global ens33
? ? ? ?valid_lft forever preferred_lft forever
? ? inet6 fe80::20c:29ff:fea1:d7ea/64 scope link?
? ? ? ?valid_lft forever preferred_lft forever
#服務器2
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
? ? link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
? ? inet 127.0.0.1/8 scope host lo
? ? ? ?valid_lft forever preferred_lft forever
? ? inet6 ::1/128 scope host?
? ? ? ?valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
? ? link/ether 00:0c:29:5c:c4:91 brd ff:ff:ff:ff:ff:ff
? ? altname enp2s1
? ? inet 172.25.254.132/24 brd 172.25.254.255 scope global ens33
? ? ? ?valid_lft forever preferred_lft forever
? ? inet6 fe80::20c:29ff:fe5c:c491/64 scope link?
? ? ? ?valid_lft forever preferred_lft forever
嘗試停止nginx服務,看是否能夠故障轉移。
sudo systemctl stop nginx
1服務器(master)
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
? ? link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
? ? inet 127.0.0.1/8 scope host lo
? ? ? ?valid_lft forever preferred_lft forever
? ? inet6 ::1/128 scope host?
? ? ? ?valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
? ? link/ether 00:0c:29:a1:d7:ea brd ff:ff:ff:ff:ff:ff
? ? altname enp2s1
? ? inet 172.25.254.131/24 brd 172.25.254.255 scope global ens33
? ? ? ?valid_lft forever preferred_lft forever
? ? inet6 fe80::20c:29ff:fea1:d7ea/64 scope link?
? ? ? ?valid_lft forever preferred_lft forever
?
2服務器(backup)
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
? ? link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
? ? inet 127.0.0.1/8 scope host lo
? ? ? ?valid_lft forever preferred_lft forever
? ? inet6 ::1/128 scope host?
? ? ? ?valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
? ? link/ether 00:0c:29:5c:c4:91 brd ff:ff:ff:ff:ff:ff
? ? altname enp2s1
? ? inet 172.25.254.132/24 brd 172.25.254.255 scope global ens33
? ? ? ?valid_lft forever preferred_lft forever
? ? inet 172.25.254.130/32 scope global ens33
? ? ? ?valid_lft forever preferred_lft forever
? ? inet6 fe80::20c:29ff:fe5c:c491/64 scope link?
? ? ? ?valid_lft forever preferred_lft forever
關閉主節點nginx服務后,能看到keepalived正常執行了故障轉移
通過Keepalived & HAProxy,實現負載均衡(Active-Active)?
在1階段的架構上,我們添加HAProxy來實現雙主負載均衡。
兩臺服務器都安裝HAProxy
sudo apt-get install haproxy
編輯HAProxy配置文件:
sudo vim /etc/haproxy/haproxy.cfg
global
? ? ? ? log /dev/log ? ?local0 info
? ? ? ? log /dev/log ? ?local1 warning
? ? ? ? chroot /var/lib/haproxy
? ? ? ? stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
? ? ? ? stats timeout 30s
? ? ? ? user haproxy
? ? ? ? group haproxy
? ? ? ? daemon? ? ? ? # 默認為ulimit -n值,并受該數值的限制
? ? ? ? # 可以當作每個連接占用32KB內存來計算出合適的數值,并分配相應的內存
? ? ? ? maxconn 60000? ? ? ? # Default SSL material locations
? ? ? ? ca-base /etc/ssl/certs
? ? ? ? crt-base /etc/ssl/private? ? ? ? # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
? ? ? ? ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
? ? ? ? ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
? ? ? ? ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-ticketsdefaults
? ? ? ? log ? ? global
? ? ? ? mode ? ?http
? ? ? ? option ?httplog
? ? ? ? option ?dontlognull
? ? ? ? retries 3
? ? ? ? timeout http-request 10s
? ? ? ? timeout connect 3s
? ? ? ? timeout client ?10s
? ? ? ? timeout server ?10s
? ? ? ? timeout http-keep-alive 10s
? ? ? ? timeout check ? ? ? ? ? 2s
? ? ? ? errorfile 400 /etc/haproxy/errors/400.http
? ? ? ? errorfile 403 /etc/haproxy/errors/403.http
? ? ? ? errorfile 408 /etc/haproxy/errors/408.http
? ? ? ? errorfile 500 /etc/haproxy/errors/500.http
? ? ? ? errorfile 502 /etc/haproxy/errors/502.http
? ? ? ? errorfile 503 /etc/haproxy/errors/503.http
? ? ? ? errorfile 504 /etc/haproxy/errors/504.httpfrontend http-in
? ? bind *:8000
? ? maxconn 20000
? ? default_backend serversbackend servers
? ? balance roundrobin
? ? server server1 172.25.254.131:80 check
? ? server server2 172.25.254.132:80 check
?
負載均衡及高可用測試
while sleep 1 ; do curl http://172.25.254.130:8000 ; done