你真的了解openFegin的降级吗?

前言

Fegin是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Fegin注解和JAX-RS注解。Fegin支持可插拔的编码器和解码器。Fegin默认集成了Ribbon,因此也可以使用负载均衡等特性,且因为遵循了SpringCloudCommon,可以与eureka、nacos等注册中心使用。

Fegin的降级熔断目前可以通过Hystrix、sentinel等实现,本文通过sentinel来实现的fegin降级。

注:fegin使用sentinel的与使用Hystrx基本一致,只是配置文件修改成下方配置即可

feign:
  sentinel:
    enabled: true

降级的基本实现

我们创建两个服务(具体代码)
在这里插入图片描述

User服务中提供一个接口用于获取获取User对象

JcRy:user对象的javabean

controller

@GetMapping("/user/test")
    public Object test(String id, HttpServletRequest request) {
    
    
        JcRy jcRy = jcRyService.getById(id);
        return jcRy;
    }

service:

    public JcRy getById(String id) {
    
    
        JcRy jcRy = jcRyDAO.selectById(id);
        return jcRy;
    }
Data服务使用fegin去调用

feginService:

@FeignClient(
        value = "service-user",
        fallbackFactory = UserServiceFallbackFactory.class

)

public interface UserService {
    
    

    @GetMapping("/user/test")
    Object test(@RequestParam String id);

}

fegin的降级:

@Component
public class UserServiceFallbackFactory implements FallbackFactory<UserService> {
    
    

    @Override
    public UserService create(Throwable throwable) {
    
    
        throwable.printStackTrace();
        System.out.println("进行降级");
        return id -> new JcRy();
    }
}
我们调用feginService中test方法后未执行降级

在这里插入图片描述

这里我们修改一下User项目的service,添加一个线程睡眠
    @Override
    public Object getById(String id) {
    
    
        //添加线程睡眠使Data服务器调用fegin报超时错误
        try{
    
    TimeUnit.MINUTES.sleep(1);}catch (Exception e){
    
    }
        JcRy jcRy = jcRyDAO.selectById(id);
        return jcRy;
    }

fegin请求超过默认超时时间是1秒,我们直接设置1分钟,这里就会报一个超时错误进而进入降级

在这里插入图片描述

通过以上例子,我们知道,当fegin调用的服务内部出现错误无法返回数据时,fegin便会进入降级方法中,但是如果fegin调用的服务内部没有出现异常,且正常返回了数据,fegin还会进入降级吗?

我们来看一下其他进入降级的方式

修改User服务中的controller:我们这次只返回一个map

    @GetMapping("/test")
    public Object test(String id, HttpServletRequest request) {
    
    
//        JcRy jcRy = jcRyService.getById(id);
        Map<String,Integer> map=new HashMap<>();
        map.put("status",400);
        return map;
    }

继续调用feginService:

在这里插入图片描述
fegin不但降级了,而且控制台没有任何报错,要知道我们的降级里有这么个代码是可以打印报错的:throwable.printStackTrace();

在这里插入图片描述
当我们跟踪源码后会发现,系统执行到了CoyoteAdapter的适配器上,该适配器对fegin的返回值进行了判断,如果存在一个status为400时,将会进入降级。这就是为什么正确返回之后也会进入降级的原因了。

在这里插入图片描述

同样在该适配器中还定义了状态status为500等返回值得降级,由此可见fegin的设计和封装真的是堪称完美啊。。

笔者是在做用网关验证时,通过fegin调用SpringSecurity的验证请求时发现了这个问题,所以以后在设计请求时可要注意这个特性,别到时候系统不明不白的就降级了。

喜欢的老铁给个免费的点赞吧,Thanks♪(・ω・)ノ

猜你喜欢

转载自blog.csdn.net/jxysgzs/article/details/106849996