提高服務器響應能力的方法
scale on 在原有服務器的基礎上進行升級或者直接換一台新的性能更高的服務器。
scale out 橫向擴展,將多台服務器並發向外響應客戶端的請求。優點:成本低,擴展架構比較簡單。
集群(Cluster),通俗地講就是按照某種組織方式將幾台電腦組織起來完成某種特定任務的這樣一種架構。
三種集群類型:
LB,Load Balancing 負載均衡:在一定程度上能夠實現高可用的目的。
HA,High Availability 高可用:實時在線,能夠及時響應客戶端請求,企業應用要求達到
7*24小時,99.999%時間在線。
HP,High Performance 高性能 提供大量超級運算能力的集群。
LB 負載均衡架構:
Director(dispatcher):負責接收客戶端請求,並將請求按照某種算法分發到后台真正提供服務的服務器上。既可以基於硬件(F5)來實現,也可以基於軟件來實現。基於軟件實現的又分為四層交換:基於IP地址和端口號組合起來對服務做重定向(LVS)。七層交換:通常指的是反向代理(proxy),例如:squid。
LVS:Linux Virtual Server
類似於iptables的架構,在內核中有一段代碼用於實時監聽數據包來源的請求,當數據包到達端口時做一次重定向。這一系列的工作必須在內核中實現。在內核中實現數據包請求處理的代碼叫做ipvs。ipvs僅僅提供了功能框架,還需要自己手動定義是數據對哪個服務的請求,
而這種定義需要通過寫規則來實現,寫規則的工具就稱為ipvsadm。
應用場景
高吞吐量(higher throughput)
冗余 (redundancy)
適應性 (adaptability)
LVS負載均衡架構
Virtual IP(VIP)address:Director用來向客戶端提供服務的IP地址
Real IP (RIP) address:集群節點(后台真正提供服務的服務器)所使用的IP地址
Director's IP (DIP) address:Director用來和D/RIP 進行聯系的地址
Client computer's IP (CIP) address:公網IP,客戶端使用的IP。
根據前端Director和后台Real Server的通信方式將LVS分為三類:
Network Address Translation(LVS-NAT)
目標地址轉換 所有客戶端的請求都被Director根據訪問請求和算法被定向到后台的Real Server 上。
數據包地址轉換過程:
S:CIP D:VIP------->Director------>S:CIP D:RIP------>Real Server------>
----->S:RIP D:CIP----->Director----->S:VIP D:CIP
Director和Real Server必須在同一個網段中;
一般情況下,RIP是私有地址,只用於集群內部節點間通信;
Director 會響應所有的請求在客戶端和Real Server之間,所承擔的負載較大;
所有的Real IP 網關必須指向DIP以響應客戶端請求;
Director可以重映射網絡端口,即前端使用標准端口,后端可以使用非標准端口;
后台的Real Server可以使用任何操作系統;
Director可能會成為系統瓶頸。
Director routing (LVS-DR )
直接路由 客戶端請求經過Director,Real Server直接回應客戶端
數據包地址轉換過程:
S:CIP D:VIP----->Director--->S:CIP D:RIP -----> Real Server---> S:VIP D:CIP
Real Server 上必須配置VIP切需要隱藏起來,只有在響應客戶端請求時才使用VIP作為源地址,除此之外並不使用此VIP。
集群節點和Director必須在同一個網絡中;
RIP不要求為私有地址;
Director僅處理所有進來的請求;
Real Server 不能以DIP作為網關,而是以公網上的某台路由器作為網關;
Director 不能再使用端口重映射;
大多數操作系統可以被用來作為Real Server,windows除外;
LVS-DR模式可以處理比LVS-NAT更多的請求。
實際生產環境中最常用的一種方式,優點:
RIP 為公網地址,管理員可以遠程連接Real Server來查看工作狀態;
一旦Director 宕機,可以通過修改DNS記錄將A記錄指向RIP 繼續向外提供服務;
IP tunneling (LVS-TUN )
與DR的網絡結構一樣,但Director和Real Server可以在不同的網絡當中,可以實現異地容災的功能。DIP----->VIP 基於隧道來傳輸,在數據包外層額外封裝了S:DIP D :RIP 的地址。
Director和Real Server 必須在同一個物理網絡中;
RIP一定不能是私有地址;
Director只負責處理進來的數據包;
Real Server直接將數據包返回給客戶端,所以Real Server默認網關不能是DIP,必須是公網上某個路由器的地址;
Director不能做端口重映射;
只有支持隧道協議的操作系統才能作為Real Server。
分發時所采用的算法
固定調度算法:按照某種既定的算法,不考慮實時的連接數予以分配。
Round-robin(RR)輪詢:當新請求到達時候,從服務列表中選擇一個Real Server,將請求重定向給這台Real Server。
Weighted round-robin(WRR)加權輪詢:給每台Real Server分配一個權重/位列,權重越大,分到的請求數越多。
Destination hashing (DH)目標散列:來自於同一個IP地址的請求都被重定向到同一台Real Server上(保證目標地址不變)。
Source hashing(SH)源地址散列:Director必須確保響應的數據包必須通過請求數據包所經過的路由器或者防火牆(保證原地址不變)。
動態調度算法:通過檢查服務器上當前連接的活動狀態來重新決定下一步調度方式該如何實現。
Lease Connection (LC) 最少連接 哪一個Real Server上的連接數少就將下一個連接請求定向到那台Real Server上去。 【算法:連接數=活動連接數*256+非活動連接數】
Weight Least-Connection(WLC) 加權最少連接 在最少連接的基礎上給每台Real Server分配一個權重。 【算法:連接數=(活動連接數*256+非活動連接數)÷權重】 一種比較理想的算法。
Shortest Expected Delay (SED) 最短期望延遲 不再考慮非活動連接數
【算法:連接數=(活動連接數+1) *256 ÷權重】
Never Queue (NQ) 永不排隊算法,對SED的改進,當新請求過來的時候不僅要取決於SED算法所得到的值,還要取決於Real Server上是否有活動連接。
Locality-Based Least-Connection (LBLC) 基於本地狀態的最少連接,在DH算法的基礎上還要考慮服務器上的活動連接數。
Locality-Based Least-Connection with Replication Scheduling (LBLCR) 帶復制的基於本地的最少連接 LBLC算法的改進
下面我們就來做一個基於LVS-NAT的負載均衡實驗:
實驗環境搭建:
Director :VIP192.168.0.127 橋接
DIP192.168.10.1 僅主機
Real Server 1:RIP 192.168.10.2 僅主機 網關指向:192.168.10.1
Real Server 2:RIP 192.168.10.3 僅主機 網關指向:192.168.10.1
Client:192.168.0.1 物理機
每台Real Server上分別安裝有http服務。我們這里為了演示效果,每個http服務的頁面不同。
Real Server 1
[root@station39 html]# ifconfig eth0 192.168.10.2
[root@station39 html]# route add default gw 192.168.10.1
Real Server 2
[root@station26 html]# ifconfig eth0 192.168.10.3
[root@station26 html]# route add default gw 192.168.10.1
Director :
[root@server27 ~]# ifconfig eth1 192.168.10.1
打開內核路由功能
[root@server27 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
確保永久有效:
[root@server27 ~]# vim /etc/sysctl.conf
# Controls IP packet forwarding
net.ipv4.ip_forward = 1
[root@server27 ~]# sysctl -p
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 4294967295
kernel.shmall = 268435456
OK,准備工作已經就緒,下面開始實驗的關鍵步驟:
[root@server27 ~]# yum install ipvsadm -y
使用步驟:1.定義服務 2 .為服務定義Real Server
[root@server27 ~]# ipvsadm -A -t 192.168.0.127:80 -s rr
[root@server27 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.127:80 rr
[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.10.2 -m -w 2
[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.10.3 -m -w 5
-g, --gatewaying Use gatewaying (direct routing). This is the default.
-i, --ipip Use ipip encapsulation (tunneling).
-m, --masquerading Use masquerading (network access transla-tion, or NAT).
PS:在這里設定的權重對於RR算法來說並沒有什么意義,我們只是為后面的實驗而設定的。
[root@server27 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.127:80 rr
-> 192.168.10.3:80 Masq 5 0 16
-> 192.168.10.2:80 Masq 2 0 15
此時,我們使用物理機訪問192.168.0.127就會發現頁面交替變化,這是由RR算法的特性決定的。
我們改變為WRR算法試試:
[root@server27 ~]# ipvsadm -E -t 192.168.0.127:80 -s wrr
[root@server27 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.127:80 wrr
-> 192.168.10.3:80 Masq 5 0 86
-> 192.168.10.2:80 Masq 2 0 43
改變為LBLC算法試試:
LBLC:基於本地狀態的最少連接,在DH算法的基礎上還要考慮服務器上的活動連接數。
[root@server27 ~]# ipvsadm -E -t 192.168.0.127:80 -s lblc
[root@server27 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.127:80 lblc
-> 192.168.10.3:80 Masq 5 0 112
-> 192.168.10.2:80 Masq 2 0 41
此時無論客戶端怎么刷新,訪問頁面都不會改變。
保存規則:
ipvsadm -S >>/etc/sysconfig/ipvs-config == ipvsadm-save
ipvsadm -R < /etc/sysconfig/ipvs-config == ipvsadm-restore
Director routing (LVS-DR )
PS:Director分發到Real Server的過程中,數據包的源地址和目標地址都沒有發生改變,Director僅僅是將目標mac地址轉換成某台Real Server的mac地址,源mac地址改為Director內網網卡的mac地址。
兩個技術難題
1 Real Server要避免對客戶端發來的對VIP的arp地址解析請求;
解決方法
1) 修改內核的兩個參數:arp_announce, arp_ignore。
arp_announce :定義不同級別:當ARP請求通過某個端口進來是否利用這個接口來回應。
0 - (default) Use any local address, configured on any interface.
利用本地的任何地址,不管配置在哪個接口上去響應ARP請求;
1 - Try to avoid local addresses that are not in the target's subnet for this interface.
避免使用另外一個接口上的mac地址去響應ARP請求;
2 - Always use the best local address for this target.
盡可能使用能夠匹配到ARP請求的最佳地址。
arp_ignore:當ARP請求發過來后發現自己正是請求的地址是否響應;
0 - (default): reply for any local target IP address, configured on any interface
利用本地的任何地址,不管配置在哪個接口上去響應ARP請求;
1 - reply only if the target IP address is local address configured on the incoming
interface.
哪個接口上接受ARP請求,就從哪個端口上回應。
PS:對linux來說IP地址屬於系統而不屬於某個接口。
2) Red Hat 提供了arptables工具,利用arp防火牆也可以實現。
2 當Real Server內網網卡響應客戶端請求時,要以VIP作為源地址,不能以RIP作為源地址。
解決方法
添加一條路由:route add -host 192.168.0.127 dev lo:0使客戶端訪問VIP,就讓VIP來響應客戶端。這樣避免了使用RIP作為源地址。
Director:VIP:響應客戶端請求;
DIP:與RIP彼此間實現arp解析,並將客戶端的請求轉發給Real Server。
實驗環境搭建:
Director :eth0:0 VIP192.168.0.127
eth0 DIP192.168.0.10 橋接
Real Server 1: eth0 RIP 192.168.0.12 橋接
lo:0 VIP 192.168.0.127
Real Server 2: eth0 RIP 192.168.0.13 橋接
lo:0 VIP 192.168.0.127
Client:192.168.0.1 物理機
Real Server 1
[root@station39 ~]# vim /etc/sysctl.conf
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
[root@station39 ~]# sysctl -p
[root@station39 ~]# ifconfig eth0 192.168.0.12/24
[root@station39 ~]# ifconfig lo:0 192.168.0.127 broadcast 192.168.0.127 netmask 255.255.255.255
[root@station39 ~]# route add -host 192.168.0.127 dev lo:0
Real Server 2
[root@station26 ~]# vim /etc/sysctl.conf
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
[root@station26 ~]# sysctl -p
[root@station26 ~]# ifconfig eth0 192.168.0.13/24
[root@station26 ~]# ifconfig lo:0 192.168.0.127 broadcast 192.168.0.127 netmask 255.255.255.255
[root@station26 ~]# route add -host 192.168.0.127 dev lo:0
Director
[root@server27 ~]# ifconfig eth0 192.168.0.10/24
[root@server27 ~]# ifconfig eth0:0 192.168.0.127 broadcast 192.168.0.127 netmask 255.255.255.255
[root@server27 ~]# route add -host 192.168.0.127 dev eth0:0
[root@server27 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@server27 ~]# ipvsadm -C
[root@server27 ~]# ipvsadm -A -t 192.168.0.127:80 -s wlc
[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.0.12 -g -w 5
[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.0.13 -g -w 8
[root@server27 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.127:80 wlc
-> 192.168.0.13:80 Route 8 0 18
-> 192.168.0.12:80 Route 5 0 11
PS:如果要保持訪問的頁面一致,我們可以另外准備一台服務器專門用來存放網頁文件,然后通過NFS共享的方式掛載到Real Server的網頁目錄下,就可以實現真正的負載均衡了。
實現持久連接:
[root@server27 ~]# ipvsadm -E -t 192.168.0.127:80 -s wlc -p 3600
[root@server27 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.127:80 wlc persistent 3600
-> 192.168.0.13:80 Route 8 0 62
-> 192.168.0.12:80 Route 5 0 0
此時,你會發現無論訪問頁面怎么刷新都不會再改變,這就是LVS持久性。
LVS Persistence 持久性
盡管我們選擇了LVS的分發方法,但是大多時候我們要保證返回給客戶端的所有響應請求必須來自於同一台Real Server,這里我們就要用到LVS Persistence(持久性)。
當使用SSL會話的時候,我們常常期望只交換一次密鑰就可以建立永久連接,因此,LVS持久性在SSL會話中經常被用到。
當使用LVS持久性的時候,Director在內部使用一個連接根據記錄稱之為“持久連接模板”來確保所有來自同一個客戶端的請求被分發到同一台Real Server上。
LVS 持久性類型:PCC PPC PNMP 混合類型。
Persistent client connections (PCC), cause all services a client is accessing to persist. (Also called zero port connections.)
來自同一客戶端所有服務的請求都被重定向到同一台Real Server上,以IP地址為准。
PCC是一個虛擬服務沒有端口號(或者端口號為0),以"-p" 來標識服務。
缺陷:定向所有服務,期望訪問不同的Real Server無法實現。
假設一個用戶在訪問購物網站時同時使用HTTP(80)和HTTPS(443)兩種協議,就需要這樣定義:
ipvsadm -A -t 192.168.0.220:0 -s rr -p
ipvsadm -a -t 192.168.0.220.3:0 -r 192.168.10.11 -m
ipvsadm -a -t 192.168.0.220:0 -r 192.168.10.11 -m
Persistent port connections (PPC), which cause a single service to persist.
來自同一服務的請求都被重定向到同一台Real Server上,以端口號為准。
例如:client---->LVS(80,22)------>RS1 client----->LVS(23)----->RS2
缺陷:期望訪問不同的端口到同一台RS上,無法實現。
Persistent Netfilter Marked Packet persistence, which causes packets that have been marked with the iptables utility to persist.
根據iptables 的規則,將對於某類服務/幾個不同端口的訪問定義為一類。
先對某一特定類型的數據包打上標記,然后再將基於某一類標記的服務送到后台的Real Server上去,后台的Real Server 並不識別這些標記。
PS:在LVS-NAT的環境下做這個實驗,由於前邊的DR模型使用了網卡別名,所以並不適合這個實驗。
[root@server27 ~]# iptables -t mangle -A PREROUTING -i eth0 -d 192.168.0.127 -p tcp --dport 80 -j MARK --set-mark 2
[root@server27 ~]# ipvsadm -A -f 2 -s wlc -p 3600
[root@server27 ~]# ipvsadm -a -f 2 -r 192.168.10.2 -m -w 2
[root@server27 ~]# ipvsadm -a -f 2 -r 192.168.10.3 -m -w 5
將持久和防火牆標記結合起來就能夠實現端口姻親功能,只要是來自某一客戶端的對某一特定服務(需要不同的端口)的訪問都定義到同一台Real Server上去。
假設這樣一種場景:一個用戶在訪問購物網站時同時使用HTTP(80)和HTTPS(443)兩種協議,我們需要將其定義到同一台Real Server上,而其他的服務不受限制,我們可以這樣做:
實驗基於LVS-NAT的環境。
先做一個自簽名的證書
Real Server 1:
[root@station39 ~]# cd /etc/pki/tls/certs/
[root@station39 ~]# cd /etc/pki/tls/certs/
[root@station39 certs]# make httpd.pem
[root@station39 certs]# mv httpd.pem /etc/httpd/
[root@station39 httpd]# yum install mod_ssl -y
[root@station39 httpd]# cd conf.d/
[root@station39 conf.d]# vim ssl.conf
SSLCertificateFile /etc/httpd/httpd.pem //** line 112
SSLCertificateKeyFile /etc/httpd/httpd.pem //** line 119
重啟httpd 服務。
[root@station39 ~]# vim /etc/hosts
192.168.10.2 web1.a.com web1
Real Server 2 :
[root@station26 ~]# yum install mod_ssl -y
[root@station26 certs]# cd /etc/httpd
[root@station26 httpd]# make -C /etc/pki/tls/certs httpd.pem
[root@station26 httpd]# mv /etc/pki/tls/certs/httpd.pem ./
[root@station26 httpd]# cd conf.d/
[root@station26 conf.d]# vim ssl.conf
SSLCertificateFile /etc/httpd/httpd.pem //** line 112
SSLCertificateKeyFile /etc/httpd/httpd.pem //** line 119
重啟httpd 服務。
[root@station26 ~]# vim /etc/hosts
192.168.10.3 web2.a.com web2
Director:
[root@server27 ~]# iptables -t mangle -A PREROUTING -i eth0 -d 192.168.0.127 -p tcp --dport 80 -j MARK --set-mark 5
[root@server27 ~]# iptables -t mangle -A PREROUTING -i eth0 -d 192.168.0.127 -p tcp --dport 443 -j MARK --set-mark 5
[root@server27 ~]# ipvsadm -A -f 5 -s wlc -p
[root@server27 ~]# ipvsadm -a -f 5 -r 192.168.10.2 -m -w 2
[root@server27 ~]# ipvsadm -a -f 5 -r 192.168.10.3 -m -w 5
OK,修改windows客戶端的C:\WINDOWS\system32\drivers\etc\hosts 文件,添加兩條名稱解析記錄:
192.168.0.127 web1.a.com
192.168.0.127 web2.a.com
此時物理機訪問192.168.0.127無論是http還是https 服務都會被定義到同一台Real Server上去。
這里我們是為了演示實驗的效果,使用的不同的證書,不同的頁面。真實的生產環境中要求這些必須是一致的。
FTP connections (FTP connections require careful handling due to the complex nature of FTP connections).
PS:指定一個范圍,將范圍內的端口打上標記。然后使VSFTPD在被動模式下不再使用隨機端口,而是使用范圍內的隨機端口,從而實現FTP的負載均衡。
1 Limiting the port range for passive connections, you must also configure the VSFTP server to use a matching port range:
vim /etc/vsftpd.conf:
pasv_min_port=10000
pasv_max_port=20000
2 You must also control the address that the server displays to the client for passive FTP connections. In a NAT routed LVS system, add the following line to /etc/vsftpd.conf to override the real server IP address to the VIP, which is what the client sees upon connection. For example:
pasv_address=n.n.n.n
3 iptables定義端口姻親:
iptables -t mangle -A PREROUTING -p tcp -d n.n.n.n/32 --dport 21 -j MARK --set-mark 21
iptables -t mangle -A PREROUTING -p tcp -d n.n.n.n/32 --dport 10000:20000 -j MARK --set-mark 21
Expired persistence, which is used internally by the Director to expire connection tracking entries when the persistent connection template expires.