全部產品
Search
文件中心

Enterprise Distributed Application Service:實現負載平衡

更新時間:Jun 30, 2024

Spring Cloud的負載平衡是通過Ribbon組件完成的。Ribbon主要提供客戶側的軟體負載平衡演算法,實現Spring Cloud中的RestTemplate和Feign用戶端底層的負載平衡。本文介紹如何使用Ribbon實現Spring Cloud應用的負載平衡。

背景資訊

Nacos整合了Ribbon的功能,NacosServerList實現了Ribbon提供的com.netflix.loadbalancer.ServerList介面。這個介面是通用的,其它類似的服務發現組件,Eureka、Consul、ZooKeeper也都實現了對應的ServerList介面,例如DomainExtractingServerList、ConsulServerList和ZookeeperServerList等。

實現該介面相當於接入了通用的Spring Cloud負載平衡規範。從Eureka、Consul、ZooKeeper等服務發現方案切換到Spring Cloud Alibaba的服務發現方案,無論是RestTemplate、FeignClient,以及已淘汰的AsyncRestTemplate,都無需修改任何代碼,即可實現負載平衡。

說明

EDAS相容Hystrix,但是前提是用戶端需要引入Hystrix的依賴。支援fallback屬性,也可以通過Sentinel實現。

您可以按照本文的內容實現應用的負載平衡,也可以直接下載應用Demo:service-providerservice-consumer

RestTemplate和Feign的實現方式有所不同,下面將分別介紹如何在您的應用中實現RestTemplate和Feign的負載平衡用法。

RestTemplate

RestTemplate是Spring提供的用於訪問REST服務的用戶端,提供了多種便捷訪問遠程HTTP服務的方法,能夠大大提高用戶端的編寫效率。

您需要在您的應用中按照下面的樣本修改代碼,以便使用RestTemplate的負載平衡功能。

public class MyApp {
    // 注入剛剛使用@LoadBalanced註解修飾構造的RestTemplate。
    // 該註解相當於給RestTemplate加上了一個攔截器:LoadBalancerInterceptor。
    // LoadBalancerInterceptor內部會使用LoadBalancerClient介面的實作類別RibbonLoadBalancerClient完成負載平衡。
    @Autowired
    private RestTemplate restTemplate;

    @LoadBalanced // 使用@LoadBalanced註解修改構造的RestTemplate,使其擁有一個負載平衡功能。
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    // 使用RestTemplate調用服務,內部會使用負載平衡調用服務。
    public void doSomething() {
        Foo foo = restTemplate.getForObject("http://service-provider/query", Foo.class);
        doWithFoo(foo);
    }

    ...
}            

Feign

Feign是一個Java實現的HTTP用戶端,用於簡化RESTful調用。

配合 @EnableFeignClients和 @FeignClient完成負載平衡請求。

  1. 使用 @EnableFeignClients開啟Feign功能。

    @SpringBootApplication
    @EnableFeignClients // 開啟Feign功能。
    public class MyApplication {
      ...
    }                        
  2. 使用 @FeignClient構造FeignClient。

    @FeignClient(name = "service-provider")
    public interface EchoService {
            @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
            String echo(@PathVariable("str") String str);
    }                        
  3. 注入EchoService並完成echo方法的調用。

    調用echo方法相當於發起了一個HTTP請求。

    public class MyService {
    @Autowired // 注入剛剛使用@FeignClient註解修飾構造的EchoService。
        private EchoService echoService;
    
        public void doSomething() {
        // 相當於發起了一個http://service-provider/echo/test請求。
        echoService.echo("test");
            }
        ...
    }                        

結果驗證

service-consumer和多個service-provider啟動後,訪問service-consumer提供的URL,確認是否實現了負載平衡。

  • RestTemplate

    多次訪問/echo-rest/rest-test查看是否轉寄到不同的執行個體。

  • Feign

    多次訪問/echo-feign/feign-test查看是否轉寄到不同的執行個體。