1. Ribbon簡介
一般來說,在生產環境中,各個微服務都會部署多個實例。那么消費者要如何將請求分攤到多個服務提供者實例上呢?負載均衡在系統架構中一個非常重要,不得不去實施的內容,負載均衡是對系統的高可用、網絡壓力的緩解和處理能力擴容的重要手段之一。通常所說的負載均衡都是指服務端負載均衡,其中分為硬件負載均衡(如F5)和軟件負載均衡(如Nginx)。Ribbon是NetFlix發布的客戶端負載均衡器,它有助於控制Http和Tcp客戶端的行為。通過SpringCloud的封裝,可以讓我們輕松的將面向服務的REST模板請求自動轉換成客戶端負載均衡的服務調用。Spring Cloud Ribbon雖然只是一個工具類框架,它不像服務注冊中心、配置中心、API網關那樣需要獨立部署,但是它幾乎存在於每一個SpringCloud構建的微服務和基礎設施中。
客戶端負載均衡和服務端負載均衡的區別?
-
服務端負載均衡

2. Ribbon的使用
-
通過Spring Cloud Ribbon的封裝,在微服務架構中使用客戶端負載均衡調用非常簡單,只需要如下兩步:
-
服務提供者只需要啟動多個服務實例並注冊到服務注冊中心
-
服務消費者直接通過調用被@LoadBalanced注解修飾過的RestTemplate來實現面向服務的接口調用
-
-
具體布步驟如下:
-
在服務消費者微服務的POM文件中添加ribbon的依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> <version>2.2.8.RELEASE</version> </dependency>
在spring cloud Eureka依賴中已經包含了spring cloud ribbon,因此無需再次引入。如過已經添加了的spring cloud Eureka依賴,不要添加該依賴,否則會遇到空指針錯誤。
-
服務提供者微服務中給RestTemplate添加@LoadBalanced注解
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }

-
對服務消費者的controller代碼進行修改
@Autowired private RestTemplate restTemplate; @Autowired private LoadBalancerClient loadBalancerClient; @GetMapping("/user/{id}") public User findById(@PathVariable long id) { //hardCode硬編碼方式不可取 //return restTemplate.getForObject("http://localhost:8000/" + id,User.class); //修改成通過微服務的虛擬主機名來訪問 return restTemplate.getForObject("http://userservice/"+id,User.class); } @GetMapping("/log-user-instance") public void logUserInstances() { ServiceInstance serviceInstance = loadBalancerClient.choose("userservice"); log.info("serviceId-->{},Host-->{},port-->{}",serviceInstance.getServiceId(),serviceInstance.getHost(),serviceInstance.getPort()); }
新增加了一個API接口,服務消費者訪問該接口時打印出IP地址和端口號

-
現在分別啟動1個服務注冊中和2個服務提供者、1個服務消費者
-
服務注冊中心

-
服務提供者

這里提供一下如何在idea中如何啟動兩個不同端口號的服務提供者的實例
-
在服務提供者的配置文件中已經配置了server.port=8000,因此第一個實例直接點擊運行就可以咯

-
選擇Idea右上角啟動按鈕邊上的Edit Configurations,在打開的對話框中,選擇UserServiceApplication-->點擊復制按鈕->VM Options中增加-Dserver.port=8001,Apply應用,如圖:

最后點擊運行就可以運行port=8001的實例咯
-
-
服務消費者
啟動服務消費者,然后不斷的訪問API接口地址http://localhost:8081/log-user-instance,發現交替打印服務消費者的ip地址。

-
-
搭建過程中遇到的問題:
添加該依賴后,運行時報空指針錯誤,去掉該依賴后能正常訪問。
報錯信息如下:

出現該問題的根本原因是Spring Cloud 2020.0.0版本以后對Spring Cloud NetFlix 組件進行剔除,僅保留了Eureka組件,其核心組件 Hystrix、Ribbon、Zuul、Archaius 等均進入維護狀態
舊版本的spring-cloud-netflix-dependencies管理着Netflix所有組件,包括Hystrix、Ribbon、Zuul、Eureka等。而自2020.0版本起,它有且只管理Eureka(包括Server和Client)
其中Feign雖然最初屬Netflix公司,但從9.x版本開始就移交給OpenFeign組織管理了,因此不再划入Netflix管轄范疇。
簡單一句話概括:Spring Cloud 2020.0.0版本徹底刪除掉了Netflix除Eureka外的所有組件

Spring Cloud 既然把 Netflix 套件大刀闊斧的砍掉了,那總歸得有替代方案吧。那是必然的,Spring Cloud 團隊給我們推薦了用於替代的組件:


Spring Cloud LoadBalancer 目前僅支持輪詢負載均衡策略,相對於 Ribbon 多種高可用策略還是過於簡單。
3. Ribbon負載均衡策略
很多場景下,可能根據需要自定義Ribbon的配置,例如修改Ribbon的負載均衡規則等。
方法一和二適合於Spring Cloud 2020.0.0版本之前的版本,方法三適合Spring Cloud 2020.0.0版之后的Spring Cloud版本
方法一:配置文件的方式
在application.propertites文件中添加如下代碼:
#更改負載均衡的負載策略
userservice.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

方法二:使用Java代碼自定義Ribbon配置
使用Ribbon提供的負載均衡策略很簡單
-
創建具有負載均衡功能的RestTemplate實例
@Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); }
使用RestTemplate進行rest操作的時候,會自動使用負載均衡策略,它內部會在RestTemplate中加入LoadBalancerInterceptor這個攔截器,這個攔截器的作用就是使用負載均衡。
-
默認情況下會采用輪詢策略,如果希望采用其它策略,則指定IRule實現,如:
@Bean public IRule ribbonRule() { return new BestAvailableRule(); }
方法三:負載均衡策略配置(適用於Spring Cloud 2020.0.0版之后的版本)
spring cloud加入了一個新模塊Spring-Loadbalancer來替代ribbon,有兩種負載均衡模式(輪詢和隨機),默認是用輪詢,假如想使用隨機或者自定義負載均衡策略,就不能按照以前使用ribbon的模式(注入IRule類,必須引入ribbon依賴),那么如果我使用Loadbalancer的隨機負載均衡,要怎么設置呢?官網給出比較詳細的方法
顯然官方寫了一個切換成隨機負載均衡的例子,我們拷貝過來即可。

@Bean ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) { String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); return new RandomLoadBalancer(loadBalancerClientFactory .getLazyProvider(name, ServiceInstanceListSupplier.class), name);
-
搭建步驟
-
把官方的@Bean方法拷貝到自己的配置類(這個類可以放到主啟動類所在包及子包下,這一點和Ribbon不同)

-
在啟動類,使用@LoadBalancerClient或者@LoadBalancerClients注解,加載自己的配置類,由此切換loadBalancer默認的負載均衡策略

-
然后運行代碼發現就切換成隨機負載均衡策略咯
-

4. Ribbon自定義負載均衡策略
可以參考這篇博客: https://blog.csdn.net/qq_35799668/article/details/114534023
