天天看點

Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用

文章目錄

  • 1、Ribbon基礎知識
  • 2、Ribbon服務調用
    • 2.1 項目中引入依賴
    • 2.2 檢視consul client中依賴的ribbon
    • 2.3 啟動consul服務注冊中心
    • 2.4 将訂單服務進行注冊
    • 2.5 将RestTemplate交給Spring工廠去管理
    • 2.6 使用RestTemplate+ribbon進行服務調用
    • 2.6.1 使用discovery client形式調用
      • 2.6.2 使用LoadBalancerClient形式調用
      • 2.6.3 使用 @LoadBalanced注解
      • 2.7 修改服務的預設負載均衡政策

1、Ribbon基礎知識

  Ribbon是Netflix用戶端的負載均衡器,可對HTTP和TCP用戶端的行為進行控制。為Ribbon配置伺服器提供者位址後,Ribbon就可以基于某種負載均衡算法自動幫助服務消費者去請求。Ribbon預設為我們提供了很多負載均衡算法,例如輪詢、随機等。當然,也可以為Ribbon實作自定義的負載均衡算法。關于詳細的負載均衡算法,請看這篇文章:

https://blog.csdn.net/qq_43753724/article/details/119836860?spm=1001.2014.3001.5501

  要将Ribbon包含在項目中,請添加如下依賴:

<!--引入ribbon依賴-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
           

  在Ribbon中有以下幾個重要概念:

  • Rule:該元件主要決定從候選伺服器中傳回哪個伺服器位址進行遠端調用的操作。
  • Ping:在背景運作的元件,用來确認那些伺服器是存貨可用的。
  • ServerList:目前可以用作LB的伺服器清單,該清單可以是靜态的,也可是動态的。如果是動态清單(例如從Eureka伺服器擷取),就會有一個背景線程按照時間間隔重新整理清單。

  Ribbon提供了以下幾種Rule:

  • RoundRobinRule:最簡單的規則,會在ServerList中依次輪詢調用。
  • RandomRule:随機。
  • AvailabilityFilteringRule:在這種規則下Ribbon內建了Hystrix的功能,預設情況下調用某個遠端方法失敗3次後斷路器的開關會被打開,而之後的請求中Ribbon會跳過這個伺服器位址,直到30秒之後斷路器關閉後才會重新加如調用清單。
  • WeightedResponseTimeRule:将響應時間作為權重的負載規則,某個伺服器的響應時間越長,它的權重就越低。具體選擇伺服器時,結合權重進行随機選擇。
  • RetryRule:按照RoundRobinRule(輪詢)政策擷取服務,如果擷取服務失敗,就在指定時間内重試,擷取可用的服務。
  • BestAvailableRule:先過濾掉由于多次通路故障而處于段力氣跳閘狀态的服務,然後選擇一個并發量最小的服務。
  • ZoneAvoidanceRule:複合判斷Server所在區域的性能和Server的可用性選擇伺服器。

2、Ribbon服務調用

2.1 項目中引入依賴

<!--引入ribbon依賴-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
           

說明:

1.如果使用的是eureka client 和 consul client,無須引入依賴,因為在eureka,consul中預設內建了ribbon元件

2.如果使用的client中沒有ribbon依賴需要顯式引入上述依賴

2.2 檢視consul client中依賴的ribbon

Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用

2.3 啟動consul服務注冊中心

Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用

2.4 将訂單服務進行注冊

訂單服務配置檔案:

Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用

  這裡注冊兩個訂單服務(模仿訂單服務叢集),一個9990端口,一個9999端口

  使用**@Value**注解将端口号注入到port變量裡面,就可以在别的服務調用的時候在頁面上列印出提供服務的伺服器節點的端口,友善觀察負載均衡的結果。

Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用
Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用

通路8500端口即可檢視服務注冊中心中所注冊的訂單服務ORDERS

Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用

2.5 将RestTemplate交給Spring工廠去管理

這樣我們就可以在需要使用的地方直接注入了。

BeansConfig.java

package com.baizhi.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration  //代表這是一個SpringBoot配置類  spring.xml  工廠  建立對象 bean id class=""
public class BeansConfig {

    //工廠中建立RestTemplate
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

           

2.6 使用RestTemplate+ribbon進行服務調用

2.6.1 使用discovery client形式調用

@Autowired      //服務注冊與發現的用戶端對象
    private DiscoveryClient discoveryClient;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("user")
    public String invokeDemo(){
         log.info("user demo...");

        //2、使用Ribbon+RestTemplate實作負載均衡調用 1.DiscoveryClient 2.LoadBalanceClient [email protected]
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances("ORDERS");
        serviceInstances.forEach(serviceInstance -> {
            log.info("服務主機:{} 服務端口:{} 服務位址:{}",serviceInstance.getHost(),serviceInstance.getPort(),serviceInstance.getUri());
       });
       String result = new RestTemplate().getForObject(serviceInstances.get(0).getUri() + "/order", String.class);
        return "OK"+result;
    }
           

在使用者服務中調用訂單服務:

http://localhost:8888/user

Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用

由于我們使用了

(serviceInstances.get(0).getUri()

,是以一緻使用的是訂單服務清單中的第一台節點,即9990端口的節點。可以看到,這裡并沒有自動幫我們做負載均衡,需要我們自己去做負載均衡的算法。

2.6.2 使用LoadBalancerClient形式調用

@RestController
@Slf4j
public class UserController {

    @Autowired      //服務注冊與發現的用戶端對象
    private DiscoveryClient discoveryClient;

    @Autowired  //負載均衡用戶端對象
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("user")
    public String invokeDemo(){
         log.info("user demo...");
        //3、使用LoadBalancerClient進行服務調用
        ServiceInstance serviceInstance = loadBalancerClient.choose("ORDERS");  //預設輪詢
        log.info("服務位址:{} 服務主機:{} 服務端口:{}",serviceInstance.getUri(),serviceInstance.getHost(),serviceInstance.getPort());
        String result = restTemplate.getForObject(serviceInstance.getUri() + "/order", String.class);


        return "OK"+result;
    }
}
           

這種方式的負載均衡算法預設使用的是輪詢方式。即第一次調用9990端口的節點,第二次就調用9999端口的節點,以此類推。

Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用
Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用

2.6.3 使用 @LoadBalanced注解

//工廠中建立RestTemplate
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
           
@RestController
@Slf4j
public class UserController {

    @Autowired      //服務注冊與發現的用戶端對象
    private DiscoveryClient discoveryClient;

    @Autowired  //負載均衡用戶端對象
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("user")
    public String invokeDemo(){
         log.info("user demo...");
        //4、使用@LoadBalance注解  作用:可以讓對象具有ribbon負載均衡特性
     String result = restTemplate.getForObject("http://ORDERS/order", String.class);
        return "OK"+result;
    }
}
           

預設還是輪詢的負載均衡算法,但是由于我們在配置檔案中添加了

#修改使用者服務調用訂單服務預設負載均衡政策不再使用輪詢 使用随機政策
ORDERS.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
           

是以,現在使用的負載均衡算法是随機法

2.7 修改服務的預設負載均衡政策

格式:

id.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
           

下圖中的ORDERS為服務的唯一辨別。

Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用
Ribbon負載均衡1、Ribbon基礎知識2、Ribbon服務調用

繼續閱讀