1. 程式人生 > >SpringCloud微服務基礎2:Robbin負載均衡

SpringCloud微服務基礎2:Robbin負載均衡

      spring Cloud Ribbon是基於Netflix Ribbon實現的一套客戶端負載均衡的工具。它是一個基於HTTP和TCP的客戶端負載均衡器。它可以通過在客戶端中配置ribbonServerList來設定服務端列表去輪詢訪問以達到均衡負載的作用。
      當Ribbon與Eureka聯合使用時,ribbonServerList會被DiscoveryEnabledNIWSServerList重寫,擴充套件成從Eureka註冊中心中獲取服務例項列表。同時它也會用NIWSDiscoveryPing來取代IPing,它將職責委託給Eureka來確定服務端是否已經啟動。
      而當Ribbon與Consul聯合使用時,ribbonServerList會被ConsulServerList來擴充套件成從Consul獲取服務例項列表。同時由ConsulPing來作為IPing介面的實現。
      我們在使用Spring Cloud Ribbon的時候,不論是與Eureka還是Consul結合,都會在引入Spring Cloud Eureka或Spring Cloud Consul依賴的時候通過自動化配置來載入上述所說的配置內容,所以我們可以快速在Spring Cloud中實現服務間呼叫的負載均衡。

         我們這裡的例子講解時按照SpringCloud微服務基礎1中高可用基礎上繼續使用的。因為Eureka中已經集成了Ribbon,所以我們無需引入新的依賴。

1、開啟負載均衡Ribbon

1.1、消費者上配置@LoadBalanced

RestTemplate的配置方法上新增@LoadBalanced註解

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}

1.2、消費者上修改呼叫方式

修改呼叫方式,不再手動獲取ip和埠,而是直接通過服務名稱呼叫:

@Service
public class UserService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    public List<User> queryUserByIds(List<Long> ids) {
        List<User> users = new ArrayList<>();
        // 地址直接寫服務名稱即可
        String baseUrl = "http://user-service/user/";
        ids.forEach(id -> {
            // 我們測試多次查詢,
            users.add(this.restTemplate.getForObject(baseUrl + id, User.class));
            // 每次間隔500毫秒
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        return users;
    }
}

2、負載均衡策略

Robbin的負載均衡策略都是在介面IRule上。

       格式是{服務名稱}.ribbon.NFLoadBalancerRuleClassName,值就是IRule的實現類 。並且springboot提供了配置負載均衡策略的:

user-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

3、Ribbon重試機制

      Eureka的服務治理強調了CAP原則中的AP,即可用性和可靠性。它與Zookeeper這一類強調CP(一致性,可靠性)的服務治理框架最大的區別在於:Eureka為了實現更高的服務可用性,犧牲了一定的一致性,極端情況下它寧願接收故障例項也不願丟掉健康例項,正如我們上面所說的自我保護機制。

      因此Spring Cloud 整合了Spring Retry 來增強RestTemplate的重試能力,當一次服務呼叫失敗後,不會立即丟擲一次,而是再次重試另一個服務。只需要簡單配置即可實現Ribbon的重試:

spring:
  cloud:
    loadbalancer:
      retry:
        enabled: true # 開啟Spring Cloud的重試功能
user-service:
  ribbon:
    ConnectTimeout: 250 # Ribbon的連線超時時間
    ReadTimeout: 1000 # Ribbon的資料讀取超時時間
    OkToRetryOnAllOperations: true # 是否對所有操作都進行重試
    MaxAutoRetriesNextServer: 1 # 切換例項的重試次數
    MaxAutoRetries: 1 # 對當前例項的重試次數

      根據如上application.yml配置,當訪問到某個服務超時後,它會再次嘗試訪問下一個服務例項,如果不行就再換一個例項,如果不行,則返回失敗。切換次數取決於MaxAutoRetriesNextServer引數的值。
引入spring-retry依賴

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>