5 远程调用 Spring Cloud Feign

目录

1 简介

2 入门案例与分析

2.1 入门案例

2.2 分析Feign的特点

3 Feign 支持负载均衡

4 Feign 支持熔断器

5 配置请求与响应压缩

6 配置日志


1 简介

前面学习中,使用RestTemplate进行远程调用的方式如下:

String baseUrl = "http://user-service/user/findById?id="+ id;
User user = restTemplate.getForObject(baseUrl, User.class)
  • RestTemplate虽然已经很简单了,但是还有一些问题:比如仍然需要自己手动把整个请求url拼出来(加了注册中心后不用再手写host+port而改成服务名)而接下来,Feign将帮助我们对调用方式进行优化。
  • Feign是一个http请求调用的轻量级框架,是以Java接口的方式调用Http接口,而不用像Java中通过封装HTTP请求报文的方式直接调用。
  • Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,进而转化成真正的请求,这种请求相对而言比较直观,再也不用去手动拼写url了。
  • Feign中已经自动集成Ribbon负载均衡

2 入门案例与分析

2.1 入门案例

目标:使用Feign替代RestTemplate发送Rest请求,使之更符合面向接口化的编程习惯。

实现步骤

  1. 导入依赖feign的starter
  2. 启动引导类加@EnableFeignClients注解
  3. 编写FeignClient接口,使用SpringMVC的注解
  4. 在Controller中注入Feign接口,直接调用,无需实现类
  5. 访问接口测试 

1 导入依赖feign的starter :



    org.springframework.cloud
    spring-cloud-starter-openfeign

2 启动引导类加@EnableFeignClients注解

@SpringCloudApplication
@EnableFeignClients//开启Feign功能
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class,args);
    }
}

3 编写FeignClient接口,使用SpringMVC的注解

  • @FeignClient注解会自动生成Feign接口的动态代理实现类,并将其注入到spring容器中
  • 接口定义的方法,采用SpringMVC的注解 @RequestMapping
  • Feign会根据注解帮我们逆向生成URL地址然后请求
  • 在Controller中注入UserService接口,直接调用,无需实现类​​​​

FeignClient接口写在工程的service层下:

//声明当前接口是feign客户端的接口,并指定feign调用的服务名为user-service
@FeignClient("user-service")
public interface UserService {
    /**
     *  接口定义的方法,采用SpringMVC的注解 @RequestMapping
     *  Feign会通过动态代理,帮我们生成该接口的实现类
     *  Feign会根据注解帮我们逆向生成URL地址然后请求
     *  在Controller中注入UserService接口,直接调用,无需实现类
     */
    @RequestMapping("/user/findById")
    User findById(@RequestParam("id") Integer id);
}

4 在Controller中注入Feign接口,直接调用,无需实现类

/**
 * 通过feign客户端发送请求
 */
@RestController
@DefaultProperties(defaultFallback = "defaultFallBackMethod")
public class FeignConsumerController {
    //注入Feign客户端的接口,直接调用
    @Autowired
    private UserService userService;

    @RequestMapping("/feign_consumer/{id}")
    public User consumerSendRequest(@PathVariable("id") Integer id){
        return userService.findById(id);
    }
}

5 测试

http://localhost:8080/feign_consumer/2

5 远程调用 Spring Cloud Feign_第1张图片

2.2 分析Feign的特点

  • 复用

哪里需要http调用,就把这个feign接口(整合了某个具体的http调用)注入到哪里,并且这个feign接口上标注了“服务名”以及“被调用服务的上下文”,一旦这些内容发生改动,只需要改一次feign接口即可,而不用每次都跑到具体的方法里面一个个去修改url地址了

  • 便于管理

同一个服务下的不同方法调用都放到了一起,便于管理,而不是零散的状态。

  • 可读性

可读性更好,更有层次感。

3 Feign 支持负载均衡

  • Feign本身集成了Ribbon,因此不需要额外引入依赖,也不需要再注册RestTemplate对象。即可无感知使用负载均衡这一特性。
  • Fegin内置Ribbon,默认设置了连接超时为1秒)和读取超时时间。我们可以通过手动配置来修改。
  • Ribbon内部有重试机制,一旦超时,会自动重新发起请求。如果不希望重试,可以修改。
# 连接超时时长:必须都要大于服务响应时间,否则一旦设置了熔断则会触发服务降级
ribbon.ConnectTimeout: 6000
# 读取数据超时时长:必须都要大于服务响应时间,否则一旦设置了熔断则会触发服务降级
ribbon.ReadTimeout: 6000
# 当前服务器的重试次数【针对请求】
ribbon.MaxAutoRetries: 0
# 重试多少次服务【针对服务】
ribbon.MaxAutoRetriesNextServer: 0
# 是否对所有的请求方式都重试
ribbon.OkToRetryOnAllOperations: false

4 Feign 支持熔断器

Feign本身也集成Hystrix熔断器,服务降级方法实现步骤:

  1. 在配置文件application.yml中开启feign熔断器支持(默认关闭)
  2. 实现FeignClient客户端接口,在实现类中编写FallBack处理类
  3. 在@FeignClient注解中,指定FallBack处理类
  4. 测试服务降级效果
  • 之前的做法:controller层收到来自浏览器的请求后,直接在方法上用@HystrixCommand来直接指定对应方法的降级方法(或者全局指定)
  • 现在的做法:在feign接口上指定了服务降级的处理类,在接口的实现类中编写服务降级的逻辑(感觉这个更合理)
  • 关于超时时间的问题请注意:Hystrix中的超时时间和Ribbon中的超时时间(连接和读取数据时间)必须都要大于服务响应时间,否则会触发熔断。

1 在配置文件application.yml中开启feign熔断器支持 :

feign.hystrix.enabled: true # 开启Feign的熔断功能

2 实现FeignClient客户端接口,在实现类中编写FallBack处理类 

/**
 * feign客户端接口的实现类:直接作为服务降级的处理类
 */
@Component
public class UserServiceImpl implements UserService {
    @Override
    public User findById(Integer id) {
        User user = new User();
        user.setUsername("服务降级处理!");
        return user;
    }
}

3 在@FeignClient注解中,指定FallBack处理类 

//声明当前接口是feign客户端的接口,并指定feign调用的服务名为user-service
//该注解会生成接口的动态代理实现类,并将其注入到spring容器中
//fallback属性:指定服务降级的处理类
@FeignClient(value = "user-service",fallback = UserServiceImpl.class)
public interface UserService {
    /**
     *  接口定义的方法,采用SpringMVC的注解 @RequestMapping
     *  Feign会通过动态代理,帮我们生成该接口的实现类
     *  Feign会根据注解帮我们逆向生成URL地址然后请求
     *  在Controller中注入UserService接口,直接调用,无需实现类(如果要用熔断,则需要写实现类)
     */
    @RequestMapping("/user/findById")
    User findById(@RequestParam("id") Integer id);
}

4 测试

http://localhost:8080/feign_consumer/1

5 远程调用 Spring Cloud Feign_第2张图片

5 配置请求与响应压缩

feign:
  compression:
    # 开启请求压缩
    request:
      enabled: true
      #开启压缩的阈值,默认2048kb
      min-request-size: 2048
      #压缩的数据类型
      mime-types: text/xml, application/xml, application/json
    # 开启响应压缩
    response:
      enabled: true

6 配置日志

  • Feign客户端是通过动态代理生成的,Feign支持在java运行时为Feign客户端的动态代理实现类进行日志配置。
  • 在发送和接收请求的时候,Feign定义了日志输出的四个等级:
级别 说明
NONE 不做任何记录
BASIC 只记录输出Http 方法名称、请求URL、返回状态码和执行时间
HEADERS 记录输出Http 方法名称、请求URL、返回状态码和执行时间 和 Header 信息
FULL 记录Request 和Response的Header,Body和一些请求元数据

Feign配置日志步骤:

  1. 在application.yml配置文件中开启日志级别配置
  2. 编写配置类,定义日志级别bean
  3. 在接口的@FeignClient中指定配置类
  4. 重启项目,测试访问

1 在application.yml配置文件中开启日志级别配置

#com.lmy.service 包下的日志级别都为Debug
logging.level.com.lmy.service: debug

2 编写配置类,定义日志级别bean

5 远程调用 Spring Cloud Feign_第3张图片

/**
 * Feign客户端接口的配置类
 */
@Configuration
public class FeignConfiguration {

    /**
     *  注入日志级别的配置到spring容器中
     */
    @Bean
    public Logger.Level loggerLevel(){
        //配置显示全部的日志信息
        return Logger.Level.FULL;
    }
}

3 在接口的@FeignClient中指定配置类

//声明当前接口是feign客户端的接口,并指定feign调用的服务名为user-service
//该注解会生成接口的动态代理实现类,并将其注入到spring容器中
//fallback属性:指定服务降级的处理类
//configuration属性:指定当前feign客户端的配置类
@FeignClient(value = "user-service",
        fallback = UserServiceImpl.class,
        configuration = FeignConfiguration.class)
public interface UserService {
    /**
     *  接口定义的方法,采用SpringMVC的注解 @RequestMapping
     *  Feign会通过动态代理,帮我们生成该接口的实现类
     *  Feign会根据注解帮我们逆向生成URL地址然后请求
     *  在Controller中注入UserService接口,直接调用,无需实现类(如果要用熔断,则需要写实现类)
     */
    @RequestMapping("/user/findById")
    User findById(@RequestParam("id") Integer id);
}

4 测试

5 远程调用 Spring Cloud Feign_第4张图片

你可能感兴趣的:(Spring,Cloud,java,http,spring,cloud)