SpringCould Feign学习

Spring Cloud Feign远程调用

RestTemplate这种方式是否还有优化空间呢?从复用、管理、可读性继续宁考虑

  • Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,是以Java接口的方式调用Http接口,而不用像Java中通过封装HTTP请求报文的方式直接调用。
  • Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。
  • Feign封装了RestTemplate

怎么实现的?

  • Feign通过注解将请求相关信息封装到接口中,当实际调用接口的时候,传入参数,根据参数加注解转化成真正的请求路径,然后使用RestTemplate发送请求,本质上,还是Http请求的发送,只不过这种相对而言比较直观。

配置

导入依赖feign的starter

<!--配置feign-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

启动引导类加@EnableFeignClients注解

Feign中已经自动集成Ribbon负载均衡

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

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

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

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

@RestController
public class FeignConsumerController {
    @Autowired
    private UserService userService;

    @RequestMapping("/feignconsumer/{id}")
    @HystrixCommand(fallbackMethod = "queryIdByFallBack")
    public User findByIdRibbon(@PathVariable("id") Integer id){
        return userService.findById(id);
    }

    public User queryIdByFallBack(Integer id){
        User user = new User();
        user.setNote("对不起,网络太拥挤了");
        return user;
    }
}

访问接口测试

踩坑: provider中的提供服务服务函数使用restful风格会报错
在这里插入图片描述
后续学习:因为在接口中使用的不是restful的风格
在这里插入图片描述

整合负载均衡

consumer中配置

  • 负载均衡是远程过程调用必备的要素。Feign本身集成了Ribbon,因此不需要额外引入依赖,也不需要再注册RestTemplate对象。即可无感知使用负载均衡这一特性。

  • Fegin内置Ribbon默认设置了连接超时,是1000毫秒(1秒)。和读取超时时间。我们可以通过手动配置来修改。Ribbon内部有重试机制,一旦超时,会自动重新发起请求。如果不希望重试,可以修改。

# 配置熔断器超时时间
# 连接超时时长
ribbon.ConnectTimeout: 6000
# 读取数据超时时长
ribbon.ReadTimeout: 6000
# 当前服务器的重试次数【针对请求】
ribbon.MaxAutoRetries: 0
# 重试多少次服务【针对服务】
ribbon.MaxAutoRetriesNextServer: 0
# 是否对所有的请求方式都重试
ribbon.OkToRetryOnAllOperations: false

整合熔断器

Feign本身也集成Hystrix熔断器,starter内查看。

服务降级方法实现步骤:

  1. 在配置文件application.yml中开启feign熔断器支持
  2. 编写FallBack处理类,实现FeignClient客户端接口
  3. 在@FeignClient注解中,指定FallBack处理类。
  4. 测试服务降级效果

实现过程:

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

    feign.hystrix.enabled: true # 开启Feign的熔断功能
    
  2. 定义一个类UserServiceFallBack,实现刚才编写的UserFeignClient,作为FallBack的处理类

    @Component//需要注意:一定要注入Spring 容器
    public class UserServiceFallBack implements UserService {
        @Override
        public User findById(Integer id) {
            User user = new User();
            user.setId(id);
            user.setUsername("用户不存在!!!");
            return user;
        }
    }
    
  3. 在@FeignClient注解中,指定FallBack处理类。。

    @FeignClient(value = "user-service",fallback = UserServiceFallBack.class)
    public interface UserService {
    
        @RequestMapping("/user/findById")
        User findById(@RequestParam("id") Integer id);
    }
    
  4. 重启测试:关闭user_service服务,然后在页面访问;http://localhost:8080/feignConsumer/2

实测设置服务提供者延时三秒,访问直接熔断,(已经加了上面的ribbon配置): 猜测问题的根源在于没有访问通过feign的路径,那怎么可能生效呢(测试后还是不行,不是路径的问题)

请求压缩和响应压缩

SpringCloudFeign支持对请求和响应进行GZIP压缩,以提升通信过程中的传输速度。

为什么RPC远程调用的方式性能更高?传输的数据量小

通过配置开启请求与响应的压缩功能:

# 开启请求压缩
feign.compression.request.enabled: true
# 开启响应压缩
feign.compression.response.enabled: true

也可以对请求的数据类型,以及触发压缩的大小下限进行设置

# 设置压缩的数据类型
feign.compression.request.mime-types:	text/html,application/xml,application/json 
# 设置触发压缩的大小下限
feign.compression.request.min-request-size: 2048 

配置日志级别

在发送和接收请求的时候,Feign定义了日志的输出定义了四个等级:这里我们配置测试一下。

级别说明
NONE不做任何记录
BASIC只记录输出Http 方法名称、请求URL、返回状态码和执行时间
HEADERS记录输出Http 方法名称、请求URL、返回状态码和执行时间 和 Header 信息
FULL记录Request 和Response的Header,Body和一些请求元数据

实现步骤:

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

实现过程:

  1. 在consumer_service的配置文件中设置com.ahu包下的日志级别都为debug

    • # com.itheima 包下的日志级别都为Debug
      logging.level:
          com.ahu: debug
      
  2. 在consumer_service编写配置类,定义日志级别

    •  @Configuration
       public class FeignConfiguration {
           @Bean
           public Logger.Level feignLoggerLevel(){
               //记录所有请求和响应的明细,包括头信息,请求体,元数据
               return Logger.Level.FULL;
           }
       }
      
  3. 在consumer_service的FeignClient中指定配置类

    • @FeignClient(value="user-service",fallback = UserServiceFallBack.class,configuration = FeignConfig.class)
      public interface UserService {
          @RequestMapping("/user/{id}")
          User queryById(@PathVariable("id") Long id);
      }
      
      
  4. 重启项目,即可看到每次访问的日志

必须访问通过feign的路径
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值