# 負載均衡 # 方式一: # 同樣資源放置多個鏈接讓用戶自己點其中一個鏈接去訪問。如:我們下載資源的時候,經常會出現“廣東電信”、“湖北電信”…… # 方式二: # 通過域名去做負載均衡,因為一個域名我們可以配置多個ip地址, # 當一個域名配置了多個IP地址后,瀏覽器通過域名訪問的時候,域名解析會輪詢返回域名所綁定的IP地址 # 但問題來了,瀏覽器通過域名解析得到與域名匹配的IP地址后,就會將域名與域名的IP存放在本地的緩存中了, # 所以下次再訪問的時候優先從本地緩存中獲取IP,而不是從DNS域名解析那里獲取。所以這種程度的負載均衡並沒有達到最大化 # 方式三:四/七層負載均衡。 # 網絡通信的七層模型分別是:1.物理層、2.數據鏈路層、3.網絡層、4.傳輸層、5.會話層、6.表示層、7.應用層 # 這里的四/七層負載均衡。對應的就是4.傳輸層、7.應用層 # 越靠近物理層進行負載均衡的效率越高 # Nginx可是實現四/七層的負載均衡。 # 所謂的四層負載均衡指的是OSI七層模型中的傳輸層,主要是基於IP+PORT的負載均衡 # 實現四層負載均衡的方式: # 硬件: F5 BIG-IP\Radware等 //硬件有一個不好的地方時,硬件在出場后就已經固定了,我們不好去拓展 # 軟件:LVS、Nginx、Hayproxe等 # 所謂七層負載均衡職到是在應用層,主要是基於虛擬的URL或主機IP的負載均衡 # 實現七層負載均衡的方式: # 軟件:Nginx、Hayproxy等 # 四層和七層負載均衡的區別 # 1.四層負載均衡數據包時在底層就進行了分發,而七層負載均衡數據包則時在頂端進行分發,所以四層負載均衡的效率比七層負載均衡的效率要高。 # 2.四層負載均衡不識別域名,而七層負載均衡識別域名。 # Nginx七層負載均衡的指令 # upstream指令:該指令是用來定義一組服務器,他們可以是監聽不同端口的服務器,並且也可以是同時監聽TCP和Unix socket的服務器。服務器可以指定不同的權重,默認為1. # 語法:upstream name {...} # 默認值:無 # 位置:http # server指令:該指令用來指定后端服務器的名稱和一些參數,可以使用域名、IP、斷后或者unix socket # 語法:server name [paramerters] # 默認值:無 # 位置:upstream # 例子: upstream backend { server 192.169.1.101; server 192.169.1.102; server 192.169.1.103; } server { listen 8082; server_name localhost; location / { proxy_pass http://backend; //這里backend就是用upstream申明的服務器組 } } # 配置完成后,192.169.1.101、192.169.1.102、192.169.1.103三台服務器循環處理用戶的訪問請求。 # 負載均很的狀態:代理服務器在負責均衡調度中的狀態有以下幾個: # down:當前的server暫時不參與負載均衡 upstream backend { server 192.169.1.101 down; server 192.169.1.102; server 192.169.1.103; } # backup:預留的備份服務器,當103當機了才會啟用102參與負載均衡 upstream backend { server 192.169.1.101 down; server 192.169.1.102 backup; server 192.169.1.103; } # max_fails:允許請求失敗的次數 # fail_timeout:經過max_fails失敗后,服務暫停時間,默認是10s; upstream backend { server 192.169.1.101 down; server 192.169.1.102 backup; server 192.169.1.103 max_fails=3 fail_timeout=15;# 當服務器請求失敗次數連續達到3次的時候,這時候103服務器就會暫停15秒不接收任何請求,這15秒會啟用102備用服務器接收處理客戶端訪問請求,15秒后103會再次處理請求,如果沒有失敗103就算恢復正常,如果再次失敗3次就繼續暫停15秒。 } # max_conns:限制最大的接受鏈接數,默認0,不做限制。防止服務器接收訪問的請求過多而導致服務器當機。 # 方便測試當即狀態,你可以在防火牆中設定端口是否放行 # 查詢防火牆中指定的端口是否開放 firewall-cmd --qurey-port=9001/tcp # 如何開放一個指定的端口 firewall-cmd --permanent --add-port=9002/tcp # 批量添加開放端口 firewall-cmd --permanent --add-port=9001-9003/tcp # 如何移除一個指定的端口 firewall-cmd --permanent --remove-port=9002/tcp # 重新加載 firewall -cmd --reload # 負載均衡策略 # Nginx默認策略是,接收客戶端訪問的請求后輪詢分發到服務器。 # 除了輪詢,Nginx還提供了其他幾種分配算法 # 輪詢:默認方式。weight=1. # weight:權重方式。也就是按比例分配。輪詢和weight一起的。 upstream backend { server 192.169.1.101 weight=10; server 192.169.1.102 weight=5; server 192.169.1.103 weight=5; } # ip_hash:依據ip分配方式,也就是訪問服務器的瀏覽器客戶端所在電腦的ip。當客戶訪問你的網站的時候需要登錄,問題來了,當你第一次訪問的時候是101服務器處理登錄的並且在101服務器上保存的session,而第二次訪問的時候是102,這個時候102是沒有session的,所以又得登錄生成session依次類推,下次訪問服務器地址又變成103的話是不是又得登錄。而這個ip_hash就是根據這個ip來分配的,當你第一次連接的是101那么往后的請求也都是在101完成的。這種方案不好的地方在於,你設置的權重或者其它算法將不起作用。要解決這個問題,你可以在三台服務器上搭建一個共同保存session的地方,比如:redis。 upstream backend { ip_hash; server 192.169.1.101; server 192.169.1.102; server 192.169.1.103; } # least_conn:依據最少連接方式。當前服務器正在連接的數量最少的優先分配。這種負載均衡策略主要是解決處理請求耗時較長的訪問。 upstream backend { least_conn; server 192.169.1.101; server 192.169.1.102; server 192.169.1.103; } # url_hash:依據URL分配方式。應用場景:客戶端訪問服務器的某個資源文件的時候,服務器不是從本地拿取文件,而是從文件系統服務器拿文件,拿到的文件如果是客戶端訪問頻繁的資源的話,服務器會將資源文件緩存到本地,下次客戶端再次訪問的時候就不需要重新去文件系統中拿取了。這樣就出現了ip_hash一樣的問題。url_hash就是解決該問題的。 upstream backend { hash $request_uri; server 192.169.1.101; server 192.169.1.102; server 192.169.1.103; } # fair:依據相應時間的方式。服務器響應越快的優先分配。 # fair算法是屬於第三方的負載均衡算法,所以你需要添加nginx-upstream-fair。 # 1.下載nginx-upstream-fair模塊 # 下載地址:https://github.com/gnosek/nginx-upstream-fair # 2.解壓縮:unzip nginx-upstream-fair.zip # 3.重命名:mv nginx-upstream-fair fair # 4.使用./configure命令將資源添加到Nginx模塊中 # ./configure -add-module=/root/fair # 5.編譯:make,這時候會報一個default_port錯誤。 # 如何解決:在Nginx的源碼中src/http/ngx_http_upstream.h中找到"ngx_http_upstream_srv_conf_s",在結構體中添加"in_port_t default_port",注意是添加不是替換。 # 6.平滑升級。 # 7.配置fair指令 upstream backend { fair; server 192.169.1.101; server 192.169.1.102; server 192.169.1.103; } # 案例一:對所有請求實現一般輪詢規則的負載均衡 upstream backend { server 192.168.200.146:9001; server 192.168.200.146:9002; server 192.168.200.146:9003; } server { listen 8083; server_name localhost; location / { proxy_pass http://backend; } } # 案例二:對所有請求實現權重輪詢規則負載均衡 upstream backend { server 192.168.200.146:9001 wight=7; server 192.168.200.146:9002 wight=7; server 192.168.200.146:9003 wight=7; } server { listen 8083; server_name localhost; location / { proxy_pass http://backend; } } # 方案三:對特定資源實現負載均衡 upstream videobackend { server 192.168.200.146:9001; server 192.168.200.146:9002; server 192.168.200.146:9003; } upstream filebackend { server 192.168.200.146:9011; server 192.168.200.146:9012; server 192.168.200.146:9013; } server { listen 8083; server_name localhost; location /video/ { proxy_pass http://videobackend; } location /file/ { proxy_pass http://filebackend; } } # 方案四:對不同域名實現負載均衡 upstream itcastbackend { server 192.168.200.146:9001; server 192.168.200.146:9002; server 192.168.200.146:9003; } upstream itheimabackend { server 192.168.200.146:9011; server 192.168.200.146:9012; server 192.168.200.146:9013; } server { listen 8085; server_name www.itcast.cn; location / { proxy_pass http://itcastbackend; } } server { listen 8086; server_name www.itheima.cn; location / { proxy_pass http://itheimabackend; } } # 案例五:實現帶有URL重寫的負載均衡 upstream backend { server 192.168.200.146:9001; server 192.168.200.146:9002; server 192.168.200.146:9003; } server { listen 8087; server_name localhost; location /file/ { rewrite ^(/file/.*) server/$1 last; } location /server { proxy_pass http://backend; } }
