Spring Cloud Nacos&Feign負載均衡

軟件方式的負載均衡一般有兩種方法

1、Nginx、Haproxy分佈式服務器網關的負載均衡;

2、Ribbon&Feign 結合Nacos本地消費者客戶端進程內的負載均衡(即不用先去訪問nginx這類的服務器網關),用於Spring Cloud;

那麼先複習下Nginx負載均衡的算法和配置。

1)、輪詢(默認)
每個請求按時間順序逐一分配到不同的後端服務器,如果後端服務器down掉,能自動剔除。
2)、weight權重
指定輪詢機率,weight和訪問比率成正比,用於後端服務器性能不均的情況。
3)、ip_hash
每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端服務器,可以解決session的問題。
4)、fair(第三方)
按後端服務器的響應時間來分配請求,響應時間短的優先分配。
5)、url_hash(第三方)

比如權重,這個weight也很好理解,權重大的被訪問的概率就大,上面這個例子的話,訪問2次server1,訪問一次server2

upstream webname {
server 192.168.0.1:8080 weight 2;
server 192.168.0.2:8080 weight 1;
}

IP hash,ip_hash的配置也很簡單,直接加一行就可以了,這樣只要是同一個ip過來的都會到同一臺server上

upstream webname {
ip_hash;
server 192.168.0.1:8080;
server 192.168.0.2:8080;

server 192.168.0.10:8090 max_fails=2 fail_timeout=1;
}

關於nginx負載均衡配置的幾個狀態參數講解。

  • down,表示當前的server暫時不參與負載均衡。

  • backup,預留的備份機器。當其他所有的非backup機器出現故障或者忙的時候,纔會請求backup機器,因此這臺機器的壓力最輕。

  • max_fails,允許請求失敗的次數,默認爲1。當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤。

  • fail_timeout,在經歷了max_fails次失敗後,暫停服務的時間。max_fails可以和fail_timeout一起使用。

基本來說,使用nginx來進行負載均衡是非常簡單的。

Ribbon&Feign 結合Nacos本地消費者進程內的負載均衡

調用方法有兩種:

1、RestTemplate

2、Openfeign

restTemplate通過服務名來訪問,restTemplate上要加上@LoadBalanced註解來實現負載均衡,底層使用的是ribbon。自動完成了通過服務名獲取調用地址列表,並選擇一個進行調用的功能。

啓動類

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class NacosApplication {
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(NacosApplication.class, args);
    }

}

RestTemplate 調用方式:


@GetMapping("/orderRibbonToMember")
public Object orderRibbonToMember() {
    //通過服務地址加上方法名調用,String.class爲方法返回值類型
    String object = restTemplate.getForObject("http://member-nacos/user", String.class);
    return "調用返回結果"+object;
}

openfeign調用方式:

SpringCloud第一代採用的是feign,第二代採用openfeign。

Openfeign客戶端是一個Web聲明式的Http客戶端遠程調用工具,底層封裝了HttpClient技術。

feign是netflix研發,而openfeign是SpringCloud自己研發的,但在使用上的代碼寫法幾乎是一致的。

在項目本地創建一個對應於要遠程調用的服務的接口,然後使用@FeignClient註解。注意,要使用@EnableFeignClients開啓openfeign

pom

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
                <version>2.0.2.RELEASE</version>
            </dependency>

接口聲明,註冊FeignClient

@FeignClient(value = "springboot2-nacos-discovery")
public interface EchoService {
    @GetMapping(value = "/echo/{string}")
    String echo(@PathVariable("string") String string);
}

使用客戶端

    @Autowired
    private EchoService echoService;
    
    @GetMapping(value = "/feignEcho/{str}")
    public String feignEcho(@PathVariable String str) {
        return echoService.echo(str);
    }

爲驗證負載均衡,我們需要把xin_cloud_nacos工程再複製一次,新工程爲xin_cloud_nacos,多開一個端口。

工程和端口:

生產者服務xin_cloud_nacos:8080

生產者服務xin_cloud_nacos1:8081

消費者客戶:8090

運行情況,Nacos發現有2個生產實例

啓動消費者發現是輪詢方式:

Hello Nacos Discovery 8080:abc
Hello Nacos Discovery 8081:abc
Hello Nacos Discovery 8080:abc
Hello Nacos Discovery 8081:abc

常見負載均衡策略

負載主機可以提供很多種負載均衡方法,也就是我們常說的調度方法或算法。

1、輪循
Round Robin: 這種方法會將收到的請求循環分配到服務器集羣中的每臺機器,即有效服務器。如果使用這種方式,所有的標記進入虛擬服務的服務器應該有相近的資源容量 以及負載形同的應用程序。如果所有的服務器有相同或者相近的性能那麼選擇這種方式會使服務器負載形同。基於這個前提,輪循調度是一個簡單而有效的分配請求 的方式。然而對於服務器不同的情況,選擇這種方式就意味着能力比較弱的服務器也會在下一輪循環中接受輪循,即使這個服務器已經不能再處理當前這個請求了。 這可能導致能力較弱的服務器超載。

2、加權輪循
Weighted Round Robin: 這種算法解決了簡單輪循調度算法的缺點:傳入的請求按順序被分配到集羣中服務器,但是會考慮提前爲每臺服務器分配的權重。管理員只是簡單的通過服務 器的處理能力來定義各臺服務器的權重。例如,能力最強的服務器 A 給的權重是 100,同時能力最低的服務器給的權重是 50。這意味着在服務器 B 接收到第一個 請求之前前,服務器 A 會連續的接受到 2 個請求,以此類推。

3、最少連接數
Least Connection: 以上兩種方法都沒有考慮的是系統不能識別在給定的時間裏保持了多少連接。因此可能發生,服務器 B 服務器收到的連接比服務器 A 少但是它已經超載,因爲 服務器 B 上的用戶打開連接持續的時間更長。這就是說連接數即服務器的負載是累加的。這種潛在的問題可以通過 “最少連接數” 算法來避免:傳入的請求是根據每 臺服務器當前所打開的連接數來分配的。即活躍連接數最少的服務器會自動接收下一個傳入的請求。接本上和簡單輪詢的原則相同:所有擁有虛擬服務的服務器資源 容量應該相近。值得注意的是,在流量率低的配置環境中,各服務器的流量並不是相同的,會優先考慮第一臺服務器。這是因爲,如果所有的服務器是相同的,那麼 第一個服務器優先,直到第一臺服務器有連續的活躍流量,否則總是會優先選擇第一臺服務器。

4、最少連接數慢啓動時間
Least Connection Slow Start Time: 對最少連接數和帶權重的最小連接數調度方法來說,當一個服務器剛加入線上環境是,可以爲其配置一個時間段,在這段時間內連接數是有限制的而且是緩慢 增加的。這爲服務器提供了一個‘過渡時間’以保證這個服務器不會因爲剛啓動後因爲分配的連接數過多而超載。這個值在 L7 配置界面設置。

5、加權最少連接
Weighted Least Connection: 如果服務器的資源容量各不相同,那麼 “加權最少連接” 方法更合適:由管理員根據服務器情況定製的權重所決定的活躍連接數一般提供了一種對服務器非常 平衡的利用,因爲他它借鑑了最少連接和權重兩者的優勢。通常,這是一個非常公平的分配方式,因爲它使用了連接數和服務器權重比例;集羣中比例最低的服務器 自動接收下一個請求。但是請注意,在低流量情況中使用這種方法時,請參考 “最小連接數” 方法中的注意事項。

6、基於代理的自適應負載均衡
Agent Based Adaptive Balancing: 除了上述方法之外,負載主機包含一個自適用邏輯用來定時監測服務器狀態和該服務器的權重。對於非常強大的 “基於代理的自適應負載均衡” 方法來說,負 載主機以這種方式來定時檢測所有服務器負載情況:每臺服務器都必須提供一個包含文件,這個文件包含一個 0~99 的數字用來標明改服務器的實際負載情況 (0 = 空前,99 = 超載,101 = 失敗,102 = 管理員禁用),而服務器同構 http get 方法來獲取這個文件;同時對集羣中服務器來說,以二進制文件形式提供自身負載情況也是該服務器工作之一,然而,並沒有限制服務器如何計算自身的負載 情況。根據服務器整體負載情況,有兩種策略可以選擇:在常規的操作中,調度算法通過收集的服務器負載值和分配給該服務器的連接數的比例計算出一個權重比 例。因此,如果一個服務器負載過大,權重會通過系統透明的作重新調整。和加權輪循調度方法一樣,不正確的分配可以被記錄下來使得可以有效的爲不同服務器分 配不同的權重。然而,在流量非常低的環境下,服務器報上來的負載值將不能建立一個有代表性的樣本;那麼基於這些值來分配負載的話將導致失控以及指令震盪。 因此,在這種情況下更合理的做法是基於靜態的權重比來計算負載分配。當所有服務器的負載低於管理員定義的下限時,負載主機就會自動切換爲加權輪循方式來分 配請求;如果負載大於管理員定義的下限,那麼負載主機又會切換回自適應方式。

7、固定權重
Fixed Weighted: 最高權重只有在其他服務器的權重值都很低時才使用。然而,如果最高權重的服務器下降,則下一個最高優先級的服務器將爲客戶端服務。這種方式中每個真實服務器的權重需要基於服務器優先級來配置。

8、加權響應
Weighted Response: 流量的調度是通過加權輪循方式。加權輪循中所使用的權重是根據服務器有效性檢測的響應時間來計算。每個有效性檢測都會被計時,用來標記它響應成功花 了多長時間。但是需要注意的是,這種方式假定服務器心跳檢測是基於機器的快慢,但是這種假設也許不總是能夠成立。所有服務器在虛擬服務上的響應時間的總和 加在一起,通過這個值來計算單個服務物理服務器的權重;這個權重值大約每 15 秒計算一次。

9、 IP 哈希
Source IP Hash: 這種方式通過生成請求源 IP 的哈希值,並通過這個哈希值來找到正確的真實服務器。這意味着對於同一主機來說他對應的服務器總是相同。使用這種方式,你不需要保存任何源 IP。但是需要注意,這種方式可能導致服務器負載不平衡,但省去了Session一致性的問題。

源碼:

完整源碼下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章