負載均衡簡介
負載均衡,英文名稱爲Load Balance,其含義就是指將負載(工作任務)進行平衡、分攤到多個操作單元上進行運行,例如FTP服務器、Web服務器、企業核心應用服務器和其它主要任務服務器等,從而協同完成工作任務。
負載均衡構建在原有網絡結構之上,它提供了一種透明且廉價有效的方法擴展服務器和網絡設備的帶寬、加強網絡數據處理能力、增加吞吐量、提高網絡的可用性和靈活性。
負載均衡分爲客戶端負載均衡和服務器端負載均衡
服務器端負載均衡:例如Nginx,通過Nginx進行負載均衡,先發送請求,然後通過負載均衡算法,在多個服務器之間選擇一個進行訪問;即在服務器端再進行負載均衡算法分配。它的一個特點是調用的客戶端不知道具體是哪一個Server提供的服務,只需要將請求發送給Nginx,再由Nginx轉發給 Tomcat,客戶端只需要記住Nginx的地址即可。即對於客戶端來說,他不關心到底是哪一個server提供服務。
客戶端負載均衡:例如spring cloud中的ribbon,客戶端會有一個服務器地址列表,在發送請求前通過負載均衡算法選擇一個服務器,然後進行訪問,這是客戶端負載均衡;即在客戶端就進行負載均衡算法分配。客戶端從自身已知的Server列表中,根據提前配置的負載均衡策略,自己挑選一個服務端來調用,此時客戶端知道自己調用的是哪一個 Server。因此從概念上可以叫做客戶端負載均衡。
從實現的角度來看,以及負載均衡策略的角度來看,客戶端負載均衡和服務端負載均衡背後實現的思想沒有本質區別。只是使用哪一個service的決定權不同。
nginx實現負載均衡
首先建立一個Spring Boot的項目對外提供服務,來模擬實際的服務,還可以配置其它可以提供網絡請求處理的框架來提供服務,這裏具體由什麼來提供服務和nginx配置並不相關,nginx只需要配置這些服務的url即可。
假設我們有如下controller
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class TestApplication {
@Value("${server.port:}")
private String port;
public static void main(String[] args) {
SpringApplication.run(TestApplication .class, args);
}
@GetMapping("")
public String hello() {
System.out.println("call me " + port);
return "Port of this instance is" + port;
}
}
將項目打包並部署兩次到不同的端口號上,模擬有多個instance的情況
java -jar test.jar --server.port=8001
java -jar test.jar --server.port=8002
然後再打開本地的nginx配置文件,配置服務器信息:
http {
upstream upstream_name{
server 192.168.0.28:8001;
server 192.168.0.28:8002;
}
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://upstream_name;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
關於配置的更多內容可以參考官方文檔:http://nginx.org/en/docs/beginners_guide.html。
當nginx配置好之後,多訪問幾次 localhost:8080。就會發現返回的東西是會變化的。
nginx的負載均衡策略有下面這幾種:
輪詢 | 默認方式 |
weight | 權重方式 |
ip_hash | 依據ip分配方式 |
least_conn | 最少連接方式 |
fair(第三方) | 響應時間方式 |
url_hash(第三方) | 依據URL分配方式 |
1.輪詢
最基本的配置方法,上面的例子就是輪詢的方式,它是upstream模塊默認的負載均衡默認策略。每個請求會按時間順序逐一分配到不同的後端服務器。
有如下參數:
fail_timeout | 與max_fails結合使用。 |
max_fails |
設置在fail_timeout參數設置的時間內最大失敗次數,如果在這個時間內,所有針對該服務器的請求都失敗了,那麼認爲該服務器會被認爲是停機了, |
fail_time | 服務器會被認爲停機的時間長度,默認爲10s。 |
backup | 標記該服務器爲備用服務器。當主服務器停止時,請求會被髮送到它這裏。 |
down | 標記服務器永久停機了。 |
注意:
- 在輪詢中,如果服務器down掉了,會自動剔除該服務器。
- 缺省配置就是輪詢策略。
- 此策略適合服務器配置相當,無狀態且短平快的服務使用。
2.weight
權重方式,在輪詢策略的基礎上指定輪詢的機率。例子如下:
upstream dynamic_zuoyu {
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082 backup; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
在該例子中,weight參數用於指定輪詢機率,weight的默認值爲1,;weight的數值與訪問比率成正比,比如Tomcat 7.0被訪問的機率爲其他服務器的兩倍。
注意:
- 權重越高分配到需要處理的請求越多。
- 此策略可以與least_conn和ip_hash結合使用。
- 此策略比較適合服務器的硬件配置差別比較大的情況。
3.ip_hash
指定負載均衡器按照基於客戶端IP的分配方式,這個方法確保了相同的客戶端的請求一直髮送到相同的服務器,以保證session會話。這樣每個訪客都固定訪問一個後端服務器,可以解決session不能跨服務器的問題。
4.least_conn
把請求轉發給連接數較少的後端服務器。輪詢算法是把請求平均的轉發給各個後端,使它們的負載大致相同;但是,有些請求佔用的時間很長,會導致其所在的後端負載較高。這種情況下,least_conn這種方式就可以達到更好的負載均衡效果。
高可用與負載均衡
高可用的定義是:高可用性”(High Availability)通常來描述一個系統經過專門的設計,從而減少停工時間,而保持其服務的高度可用性。白話來講,高可用對於系統來說就是讓這個系統在大多的時間裏都是可以使用的。一個反例是12306系統,12306在每天11點之後就不能再進行操作,從這個角度來說其系統不具備高可用的特徵。
高可用集羣中的節點一般是一主一備,或者一主多備,通過備份提高整個系統可用性。
而負載均衡集羣一般是多主,每個節點都分擔流量