1. 程式人生 > 實用技巧 >SpringCloud之Ribbon負載均衡

SpringCloud之Ribbon負載均衡

上述案例中,我們啟動了一個msg-service,然後通過DiscoveryClient來獲取服務例項資訊,然後獲取ip和埠來訪問。

但是實際環境中,我們往往會開啟很多個user-service的叢集。此時我們獲取的服務列表中就會有多個,到底該訪問哪一個呢?

一般這種情況下我們就需要編寫負載均衡演算法,在多個例項列表中進行選擇。

不過Eureka中已經幫我們集成了負載均衡元件:Ribbon,簡單修改程式碼即可使用。

什麼是Ribbon:


Ribbon的使用步驟

一、首先啟動兩個msg-server服務

二、開啟Ribbon負載均衡

  因為Eureka中已經集成了Ribbon,所以我們無需引入新的依賴。直接修改程式碼:

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

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

package com.itcast.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.ribbon.proxy.annotation.Hystrix;
import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.netflix.hystrix.EnableHystrix; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import
org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.client.RestTemplate; import java.util.List; /** * @Classname MsgController * @Description TODO * @Date 2020/12/18 10:21 * @Created by Administrator */ @Controller public class MsgController { @Autowired RestTemplate restTemplate; @Autowired DiscoveryClient discoveryClient; @RequestMapping("hello") @ResponseBodypublic String hello(){ String url="http://msg-server/hello"; String forObject = restTemplate.getForObject(url, String.class); return forObject; } }

修改負載均衡規則

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

重試機制

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

  但是,此時如果我們呼叫了這些不正常的服務,呼叫就會失敗,從而導致其它服務不能正常工作!這顯然不是我們願意看到的。

  因此Spring Cloud 整合了Spring Retry 來增強RestTemplate的重試能力,當一次服務呼叫失敗後,不會立即丟擲異常,而是再次重試另一個服務。

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

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

  附:引入spring-retry依賴

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