SpringCloud Feign 服務調用組件1:使用負載均衡 Ribbon

Spring Cloud Feign  是聲明式的 Web 服務客戶端,我們只需創建一個接口並用註解的方式來配置它,就可以實現對某個服務接口的調用,簡化了直接使用RestTemplate 來調用服務接口的開發量。Feign 具備可插拔的註解支持,同時支持Feign註解、JAX-RS 註解及 SpringMvc 註解。Feign 整合了 Ribbon 和 Hystrix,擁有負載均衡和服務容錯功能。

聲明式的 Web 服務客戶端定義的方式:通過編寫簡單的接口和註解,就可以定義好 HTTP 請求的參數、格式、地址等信息。Feign 會完全代理 HTTP 的請求,在使用過程中我們只需要依賴注入 Bean,然後調用對應的方法傳遞參數即可。

 

一、準備工作

1.1、創建啓動一個註冊中心,二個服務提供者

請參考:SpringCloud Eureka 服務註冊中心組建1:搭建註冊中心

  • piao-server:服務註冊中心,端口2000。
  • piao-client:客戶服務端提供者,端口2010。
  • piao-client2:客戶服務端提供者,端口2011。

如果不想創建多個項目,可以請考這篇文章:IDEA 啓動多個SpringBoot項目不同端口

啓動成功如下:

 

二、創建服務消費者 Feign

2.1、創建 piao-feign 項目。

我們這裏使用IDEA創建,文件-》新建-》項目-》下一步到如下的頁面:

我們選擇以上兩個依賴包。然後在點下一步,直到完成。

 

2.2、修改依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.piao</groupId>
    <artifactId>piao-feign</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>piao-feign</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </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-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 

2.3、添加配置

編輯項目的 application.properites 文件,添加如下相關配置:

#服務註冊中心端口號
server.port=2007

#指定服務名稱
spring.application.name=piao-feign
#指定服務註冊中心的地址
eureka.client.serviceUrl.defaultZone=http://localhost:2000/eureka/

在啓動類上添加 @EnableFeignClients 註解開啓 Spring Cloud Feign 的支持功能。

@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class PiaoFeginApplication {

    public static void main(String[] args) {
        SpringApplication.run(PiaoFeginApplication.class, args);
    }

}

 

2.4、編寫 Service, 使用 Feign 客戶端的調用。 

@FeignClient("piao-client")
public interface ConsumerService {

    @RequestMapping("/client")
    String client();

    @RequestMapping("/param")
    String param(@RequestParam String param);

}

這裏的服務名不區分大小寫,所以使用 hello-service 和 HELLO-SERVICE 都是可以的。

 

2.5、編寫Controller

@RestController
public class ConsumerController {

    @Autowired
    private ConsumerService consumerService;

    @GetMapping("/consumer")
    public String consumer() {
        return consumerService.client();
    }

    @GetMapping("/param")
    public String param(@RequestParam String param) {
        return consumerService.param(param);
    }

}

 

2.6、啓動項目

我們訪問註冊中心地址:http://127.0.0.1:2000/

請求服務消費者地址:http://127.0.0.1:2007/consumer

請求服務消費者地址:http://127.0.0.1:2007/param?param=piao

第一次訪問:

第二次訪問:

可以看到我們實現負載均衡,這裏就是 Fegin 整合了 Ribbon 功能。

 

三、Feign 重試機制

在 Spring Cloud Feign 中默認實現了請求的重試機制。

Ribbon 的超時與 Hystrix 的超時是兩個概念。爲了讓上述實現有效,我們需要讓 Hystrix 的超時時間大於 Ribbon 的超時時間,否則 Hystrix 命令超時後,該命令直接熔斷,重試機制就沒有任何意義了。

全局配置:

#斷路器的超時時長需要大於Ribbon的超時時間,不然不會觸發重試
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000

#請求連接超時時間(毫秒)
ribbon.ConnectTimeout=1000
#請求處理的超時時間(毫秒)
ribbon.ReadTimeout=3000
#對所有請求都進行重試(是否所有操作都重試,若false則僅get請求重試)
ribbon.OkToRetryOnAllOperations=true
#切換實例的重試次數
ribbon.MaxAutoRetriesNextServer=2
#對當前實例的重試次數
ribbon.MaxAutoRetries=1

指定服務配置:

#斷路器的超時時長需要大於Ribbon的超時時間,不然不會觸發重試
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000

#請求連接超時時間(毫秒)
piao-client.ribbon.ConnectTimeout=1000
#請求處理的超時時間(毫秒)
piao-client.ribbon.ReadTimeout=3000
#對所有請求都進行重試(是否所有操作都重試,若false則僅get請求重試)
piao-client.ribbon.OkToRetryOnAllOperations=true
#切換實例的重試次數
piao-client.ribbon.MaxAutoRetriesNextServer=2
#對當前實例的重試次數
piao-client.ribbon.MaxAutoRetries=1

當訪問到故障請求的時候,它會再嘗試訪問一次當前實例(次數由 MaxAutoRetries 配置),如果不行,就換一個實例進行訪問,如果還不行,再換一次實例訪問(更換次數由 MaxAutoRetriesNextServer 配置),如果依然不行,返回失敗信息。

 

四、配置負載均衡策略

全局配置:

#修改負載均衡算法
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

指定服務配置:

#修改負載均衡算法
piao-client.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

Ribbon的負載均衡策略:

  • com.netflix.loadbalancer.RandomRule:從提供服務的實例中以隨機的方式;
  • com.netflix.loadbalancer.RoundRobinRule:以線性輪詢的方式,就是維護一個計數器,從提供服務的實例中按順序選取,第一次選第一個,第二次選第二個,以此類推,到最後一個以後再從頭來過;
  • com.netflix.loadbalancer.RetryRule:在RoundRobinRule的基礎上添加重試機制,即在指定的重試時間內,反覆使用線性輪詢策略來選擇可用實例;
  • com.netflix.loadbalancer.WeightedResponseTimeRule:對RoundRobinRule的擴展,響應速度越快的實例選擇權重越大,越容易被選擇;
  • com.netflix.loadbalancer.BestAvailableRule:選擇併發較小的實例;
  • com.netflix.loadbalancer.AvailabilityFilteringRule:先過濾掉故障實例,再選擇併發較小的實例;
  • com.netflix.loadbalancer.ZoneAwareLoadBalancer:採用雙重過濾,同時過濾不是同一區域的實例和故障實例,選擇併發較小的實例。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章