提升服務器響應能力的方法html
scale on 在原有服務器的基礎上進行升級或者直接換一臺新的性能更高的服務器。前端
scale out 橫向擴展,將多臺服務器併發向外響應客戶端的請求。優勢:成本低,擴展架構比較簡單。linux
集羣(Cluster),通俗地講就是按照某種組織方式將幾臺電腦組織起來完成某種特定任務的這樣一種架構。web
三種集羣類型:算法
LB,Load Balancing 負載均衡:在必定程度上可以實現高可用的目的。vim
HA,High Availability 高可用:實時在線,可以及時響應客戶端請求,企業應用要求達到windows
7*24小時,99.999%時間在線。後端
HP,High Performance 高性能 提供大量超級運算能力的集羣。服務器
LB 負載均衡架構:cookie
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.