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:采用双重过滤,同时过滤不是同一区域的实例和故障实例,选择并发较小的实例。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章