开启一个spring cloud 工程 -第六步Feign 声明式接口调用以及使用Hystrix的熔断实现

Feign

  • 什么是Feign

Feign 与Ribbon 一样,Feign也是有Netflix 提供的,Feign是一个声明式、模块化的Web Service 客户端,它简化了开发者编写Web服务客户端的操作,开发者可以通过简单的接口和注解来调用HTTP API,Spring Cloud Feign,它整合了Ribbon 和Hystrix ,具有可插拔、基于注解、负载均衡、服务熔断等一系列便捷功能。

相比较于Ribbon +RestTemplate 的方式,Feign 大大简化了代码的开发,Feign 支持多种注解,包括Feign 注解、JAX-RS注解、Spring MVC注解等,Spring Cloud 对Feign 进行了优化,整合了Ribbon 和Eureka ,从而让Feign 的使用更加方便。

  • Ribbon 和Feign 的区别

    1、 Fiegn 是一个声明式的Web Service 客户端。
    2、支持Feign 注解、Spring MVC注解、JAX-RS注解。
    3、Feign 基于Ribbon 实现,使用起来更加简单。
    4、Feign 集成了Hystrix ,具备服务熔断的功能。

开启Feign 的功能

1、创建新的Module ,命名为 feign ,pom.xml 添加以下依赖

<dependencies>
    <!-- 都是作为服务注册到Eureka Server ,所以需要添加这个依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        <version>2.0.2.RELEASE</version>
    </dependency>
    <!-- Feign 的依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
        <version>2.0.2.RELEASE</version>
    </dependency>
</dependencies>

2、 新建application.yml文件
内容如下:

server:
  port: 8050
spring:
  application:
      name: feign
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

3、创建启动类,并添加上Feign相关的注解
启动类名称取名为FeignApplication
代码如下:

package com.southwind;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class FeignApplication {
    
    
    public static void main(String[] args){
    
    
        SpringApplication.run(FeignApplication.class,args);
    }
}

4、因为还需要继续操作第一篇文章建的学生实体类,所以需要把原来的实体类代码复制过来
Student 类:

package com.southwind.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor                 //无参构造
@AllArgsConstructor                //有参构造
public class Student {
    
    
    private long id;
    private String name;
    private int age;

}

目录结构如下:
在这里插入图片描述

4、 新建一个名叫 FeignProviderClient 的接口 放在com.southwind.feign 包里

FeignProviderClient 代码如下:


```java
package com.southwind.feign;

import com.southwind.entity.Student;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Collection;

//这里就体现了Feign 的声明式调用,都是接口,
//value = provider是因为提供者在注册中心的名字叫做 provider
@FeignClient(value = "provider")
public interface FeignProviderClient {
    
    
   /* 需要调用提供者的controller 里面的方法,直接就行(有
    * 点相当于它自己就会把provider 替换成IP地址,然后把Mapping 里面的值给拼接
    * 到后面,实现模块间的调用。)
    */
    @GetMapping("/student/findAll")
    public Collection<Student> findAll();
    @GetMapping("/student/index")
    public String index();
}

5、创建controller ,命名为FeignHandler.java ,存放在com.southwind.controller 文件夹里

package com.southwind.controller;

import com.southwind.entity.Student;
import com.southwind.feign.FeignProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;

@RestController
@RequestMapping("/feign")
public class FeignHandler {
    
    
    @Autowired
    private FeignProviderClient feignProviderClient;

    @GetMapping("/findAll")
    public Collection<Student> findAll(){
    
    
        return feignProviderClient.findAll();
    }

    @GetMapping("/index")
    public String index(){
    
    
        return feignProviderClient.index();
    }
}

6、启动注册中心eruekaserver,然后与上一篇文章一样,一个工程启动两个不同端口的提供者服务,启动eurekaclient,然后启动feign 工程

7、在浏览器输入:localhost:8050/feign/index

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Feign 声明式调用 也可以实现了负载均衡,并且比用zuul 网关的方法,简化了代码,更方便。

使用Feign 实现服务的熔断

什么是熔断。
当微服务处理秒杀场景,或者类似场景,导致访问服务器并发量特别大的时候,有可能一个服务崩了,导致调用它的服务因为长时间等不到该服务的响应继而也发生崩溃,以此类推,导致“雪崩效应”。这时候熔断器发挥了作用,他像电路的熔断器一样,一旦电流超过了最大电流,熔断器就断电,防止漏电和触电事件的发生。当某一个服务一直调用不无响应时,熔断器启动,暂时停止访问该服务,并且返回一个熔断处理的结果,告知用户稍后再试。等待宕机的服务重新恢复正常。待服务可以正常访问后,熔断器自动关闭。

1、在原来feign 工程的yml文件,添加feign熔断开启的代码。

server:
  port: 8050
spring:
  application:
    name: feign
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
feign:
  hystrix:
    enabled: true

feign.hystrix.enabled:true 是否开启熔断器

2、创建FeignProviderClient 的实现类FeignError, 定义容错处理逻辑,通过@Component 注解将FeignError实例注入IoC容器中。

在这里插入图片描述
FeignError 代码:

package com.southwind.feign.impl;

import com.southwind.entity.Student;
import com.southwind.feign.FeignProviderClient;
import org.springframework.stereotype.Component;

import java.util.Collection;
@Component
public class FeignError implements FeignProviderClient {
    
    
    @Override
    public Collection<Student> findAll() {
    
    
        return null;
    }
//当熔断开启时,停止对该服务的访问,然后调用此方法告知用户系统繁忙
    @Override
    public String index() {
    
    
        return "服务器维护中.....";
    }
}

3、在FeignProviderClient 定义处通过 @FeignClient 的fallback 属性设映射,降级处理。

在FeignProviderClient 中,增加降级处理(红色框框部分)
在这里插入图片描述
这时候,一旦Feign 访问服务提供者,服务提供者不是正常状态导致feign 访问不成功的话,他自己就会找到feignError 里面的fallback 方法进行处理。这样,就不会出现网页状态码,如500,404等,而是会出现你写的fallback ,即熔断处理的方法里面。

4、测试

先把服务提供者停掉,这时候使用 feign 调用提供者 ,会报500,即服务器没有响应。
在这里插入图片描述

这时候重新启动feign(开启feign 熔断后,还没有生效,现在重启feign 使熔断生效)

重新在浏览器访问:localhost:8050/feign/index

在这里插入图片描述
成功启动了熔断器。因为提供者调不通,所以直接调用自己熔断方法。

猜你喜欢

转载自blog.csdn.net/chenmaolin928/article/details/109184353
今日推荐