#一、概述 ##1.1、Ribbon Spring Cloud Ribbon是基於Netflix Ribbon實現的一套客戶端負載均衡的工具。簡單的說,Ribbon是Netflix發佈的開源項目,主要功能是提供客戶端的軟體負載均衡演算法和服務調用。Spring Cloud Ribbon雖然只是一個工具 ...
一、概述
1.1、Ribbon
Spring Cloud Ribbon是基於Netflix Ribbon實現的一套客戶端負載均衡的工具。簡單的說,Ribbon是Netflix發佈的開源項目,主要功能是提供客戶端的軟體負載均衡演算法和服務調用。Spring Cloud Ribbon雖然只是一個工具類框架,它不像服務註冊中心、配置中心、API網關那樣需要獨立部署,但是它幾乎存在於每一個Spring Cloud構建的微服務和基礎設施中。但是Ribbon已經進入了維護模式。後續我們將要介紹的Feign,它也是基於Ribbon實現的工具。所以,對Spring Cloud Ribbon的理解和使用,對於我們使用Spring Cloud來構建微服務非常重要。
官網地址 >> https://github.com/Netflix/ribbon/wiki/Getting-Started
spring-cloud-starter-netflix-eureka-client自帶了spring-cloud-starter-ribbon引用
1.2、Feign
Feign是聲明式的web service客戶端,它讓微服務的調用變得更簡單了,類似Controller調用service。SpringCloud集成了Ribbon和Eureka,可在使用Feign時提供負載均衡的http客戶端。只需要創建一個介面,然後添加註解即可!
二、負載均衡
2.1、Ribbon核心組件
IRule:根據特定演算法從服務列表中選取一個要訪問的服務。
- com.netflix.loadbalancer.RoundRobinRule 輪詢
- com.netflix.loadbalancer.RandomRule 隨機
- com.netflix.loadbalancer.RetryRule 先按照RoundRobinRule的策略獲取服務,如果獲取服務失敗則在指定時間內會進行重試
- WeightedResponseTimeRule 對RoundRobinRule的擴展,響應速度越快的實例選擇權重越大,越容易被選擇
- BestAvailableRule 會先過濾掉由於多次訪問故障而處於斷路器跳閘狀態的服務,然後選擇一個併發量最小的服務
- AvailabilityFilteringRule 先過濾掉故障實例,再選擇併發較小的實例
- ZoneAvoidanceRule 預設規則,複合判斷server所在區域的性能和server的可用性選擇伺服器
2.2、替換Ribbon的負載均衡規則
2.2.1 首先,在主啟動類的上一級目錄創建一個myrule包,用於存放我們的rule配置。
2.2.2 創建一個MyRuleConfig 類,並new 一個新的IRule 實例Bean。
package com.cpown.myrule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 創建新的ruleBean
* create by c-pown on
*/
@Configuration
public class MyRuleConfig {
@Bean
public IRule iRule(){
return new RandomRule();
}
}
2.2.3 在主啟動類添加 @RibbonClient註解 指定我們需要應用自定義負載均衡演算法的微服務名稱,以及演算法類class;
package com.atguigu.springcloud;
import com.atguigu.myrule.MySelfRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
/**
* @auther zzyy
* @create 2020-01-28 16:18
* 在啟動該微服務的時候就能去載入我們的自定義Ribbon配置類,從而使配置生效,形如:
*/
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration=MySelfRule.class)
public class OrderMain80
{
public static void main(String[] args)
{
SpringApplication.run(OrderMain80.class,args);
}
}
啟動項目即可實現替換的負載均衡演算法了。
輪詢負載均衡演算法:rest介面第幾次請求數 % 伺服器集群總數量 = 實際調用伺服器位置下標 ,每次服務重啟動後rest介面計數從1開始。
三、OpenFeign
3.1、OpenFeign使用步驟
1、新建cloud-consumer-feign-order80
2、POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mscloud03</artifactId>
<groupId>com.atguigu.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumer-feign-order80</artifactId>
<dependencies>
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 引入自己定義的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--一般基礎通用配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3、YML
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
4、業務類
業務邏輯介面+@FeignClient配置調用provider服務,
新建PaymentFeignService介面並新增註解@FeignClient
package com.atguigu.springcloud.service;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @auther zzyy
* @create 2020-02-03 12:00
*/
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService
{
@GetMapping(value = "/payment/get/{id}")
CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}
5、小總結
openfeign的實現原理:基於@EnableFeignClients 將所有被@FeignClient註解的類 註冊到容器中。當這些被@FeignClient註解的類被調用時會創建一個動態代理的對象為我們創建被調用類的實例,然後都會被統一轉發給 Feign 框架所定義的一個 InvocationHandler , 由該 Handler 完成後續的 HTTP 轉換, 發送, 接收, 翻譯HTTP響應的工作。
3.2、OpenFeign超時控制
預設Feign客戶端只等待一秒鐘,但是服務端處理需要超過1秒鐘,導致Feign客戶端不想等待了,直接返回報錯。為了避免這樣的情況,有時候我們需要設置Feign客戶端的超時控制。
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
#設置feign客戶端超時時間(OpenFeign預設支持ribbon)
ribbon:
#指的是建立連接所用的時間,適用於網路狀況正常的情況下,兩端連接所用的時間
ReadTimeout: 5000
#指的是建立連接後從伺服器讀取到可用資源所用的時間
ConnectTimeout: 5000
3.3、OpenFeign日誌列印功能
Feign 提供了日誌列印功能,我們可以通過配置來調整日誌級別,從而瞭解 Feign 中 Http 請求的細節。說白了就是對Feign介面的調用情況進行監控和輸出
日誌級別:
- NONE:預設的,不顯示任何日誌;
- BASIC:僅記錄請求方法、URL、響應狀態碼及執行時間;
- HEADERS:除了 BASIC 中定義的信息之外,還有請求和響應的頭信息;
- FULL:除了 HEADERS 中定義的信息之外,還有請求和響應的正文及元數據。
日誌配置類:
package com.atguigu.springcloud.cfgbeans;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import feign.Logger;
/**
* @auther LayTao
* @create 2019-11-10 17:00
*/
@Configuration
public class FeignConfig
{
@Bean
Logger.Level feignLoggerLevel()
{
return Logger.Level.FULL;
}
}
# YML文件里需要開啟日誌的Feign客戶端
logging:
level:
# feign日誌以什麼級別監控哪個介面
com.atguigu.springcloud.service.PaymentFeignService: debug