转自:https://www.jianshu.com/p/d84768f7996d
Spring Cloud Feign 之Fallback
环境信息: java 1.8、Spring boot 1.5.10.RELEASE、spring cloud-Edgware.SR3、maven 3.3+
在网络请求时,可能会出现异常请求,如果还想再异常情况下使系统可用,那么就需要容错处理,比如:网络请求超时时给用户提示“稍后重试”或使用本地快照数据等等。
Spring Cloud Feign就是通过Fallback
实现的,有两种方式:
1、@FeignClient.fallback = UserFeignFallback.class
指定一个实现Feign接口的实现类。
2、@FeignClient.fallbackFactory = UserFeignFactory.class
指定一个实现FallbackFactory<T>
工厂接口类
因为Fallback
是通过Hystrix
实现的, 所以需要开启Hystrix
,spring boot application.properties
文件配置feign.hystrix.enabled=true
,这样就开启了Fallback
Fallback-实现Feign接口
UserFeignFallback
回调实现,由spring创建使用@Component
(其他的注册也可以)注解
HystrixTargeter.targetWithFallback
方法实现了@FeignClient.fallback
处理逻辑,通过源码可以知道UserFeignFallback
回调类是从Spring容器中获取的,所以UserFeignFallback
由spring创建。
UserFeign
配置:
package com.example.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
@FeignClient(name = "user",url = "${user.url}",fallback = UserFeignFallback.class
/*fallbackFactory = UserFeignFactory.class*/)
public interface UserFeign {
@PostMapping
void save(User user);
@GetMapping("/{id}")
User getUserByID(@PathVariable("id") String id);
@GetMapping
List<User> findAll();
}
UserFeignFallback
类:
package com.example.feign;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class UserFeignFallback implements UserFeign {
@Override
public void save(User user) {
}
@Override
public User getUserByID(String id) {
User user = new User();
user.setId("100");
user.setName("fallback 回调用户");
return user;
}
@Override
public List<User> findAll() {
return null;
}
}
为了模拟回调失败服务提供方,抛出500错误。
@GetMapping("/{id}")
public User getUserByID(@PathVariable("id") String id) {
// return userMap.get(id);
throw new RuntimeException("服务端测试异常!");
}
运行单元测试UserFeignTest.getUserByID
控制台输出结果:
2018-08-18 11:47:59.800 INFO 8660 --- [ hystrix-user-1] com.example.feign.UserFeign : [UserFeign#getUserByID] ---> GET http://localhost:8080/user/1 HTTP/1.1
2018-08-18 11:47:59.800 INFO 8660 --- [ hystrix-user-1] com.example.feign.UserFeign : [UserFeign#getUserByID] ---> END HTTP (0-byte body)
2018-08-18 11:47:59.828 INFO 8660 --- [ hystrix-user-1] com.example.feign.UserFeign : [UserFeign#getUserByID] <--- HTTP/1.1 500 (27ms)
2018-08-18 11:47:59.828 INFO 8660 --- [ hystrix-user-1] com.example.feign.UserFeign : [UserFeign#getUserByID] connection: close
2018-08-18 11:47:59.828 INFO 8660 --- [ hystrix-user-1] com.example.feign.UserFeign : [UserFeign#getUserByID] content-type: application/json;charset=UTF-8
2018-08-18 11:47:59.828 INFO 8660 --- [ hystrix-user-1] com.example.feign.UserFeign : [UserFeign#getUserByID] date: Sat, 18 Aug 2018 03:47:59 GMT
2018-08-18 11:47:59.828 INFO 8660 --- [ hystrix-user-1] com.example.feign.UserFeign : [UserFeign#getUserByID] transfer-encoding: chunked
2018-08-18 11:47:59.828 INFO 8660 --- [ hystrix