前言
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
降级的基本实现
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;
}
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();
}
}
@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分钟,这里就会报一个超时错误进而进入降级
我们来看一下其他进入降级的方式
修改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♪(・ω・)ノ