七、Fegin为消费者提供封装(可选)
- 完整工程源码:https://gitee.com/forwardxiang/spring-cloud-demo.git
7.1 导入依赖
-
在消费者原有的依赖基础上新增:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
7.2 编写Feign客户端
-
编写一个接口并交给spring容器,产生代理接口对象,供用户在controller中自动注入后使用:
@FeignClient("bill-manager") public interface UserClient { //http://bill-manager/bill/123 @GetMapping("/bill/{id}") User queryById(@PathVariable("id") Long id); }
-
编写controller接口,不再出现需要访问的服务ip或者service-id,全由代理对象完成:
@RestController @RequestMapping("/cf") public class ConsumerFeignController { @Autowired private UserClient userClient; @GetMapping("/{id}") public Bill queryById(@PathVariable Long id){ return userClient.queryById(id); } }
7.3 开启Fegin功能
-
在启动类上添加@EnableFeignClients 注解开启Fegin功能:
//@SpringBootApplication //@EnableDiscoveryClient //@EnableCircuitBreaker @SpringCloudApplication //相当于上面三个注解的组合 @EnableFeignClients //开启feign功能,已经自动集成了Ribbon负载均衡 public class ApiGatewayApplication { public static void main(String[] args) { SpringApplication.run(ApiGatewayApplication.class, args); } //注意此处不再@Bean和@LoadBalanced来定义RestTemplate进行负载均衡的配置。 }
7.4 Fegin相关配置
-
Feign默认也有对Hystrix的集成,但是默认关闭,如果需要开启则在yml配置文件:
feign: hystrix: enabled: true # 开启Feign的熔断功能
-
给集成的Hystrix编写Fallback回调,首先是实现Feign客户端接口:
@Component public class UserClientFallback implements UserClient { @Override public User queryById(Long id) { User user = new User(); user.setId(id); user.setName("用户异常"); return user; } }
-
然后将这个实现类作为Fallback回调指定给他的接口:
@FeignClient("bill-manager",fallback = UserClientFallback.class) public interface UserClient { //http://bill-manager/bill/123 @GetMapping("/bill/{id}") User queryById(@PathVariable("id") Long id); }
-
这样在发生雪崩等导致服务降级的问题时,如果请求这个配置过Fegin内置Hystrix的接口,就回返回给请求者对应的fallback。
7.5 单独引入Hystrix(配置更容易)
-
引入依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
-
启动类上添加注解@EnableCircuitBreaker。
-
在controller里编写需要指定fallback的方法同样返回值和参数声明的方法:
public String queryByIdFallback(Long id) { log.error("查询用户信息失败。id:{}", id); return "对不起,网络太拥挤了!"; }
-
将该fallback在正常逻辑的方法上注明:
@GetMapping("{id}") @HystrixCommand(fallbackMethod = "queryByIdFallback") public String queryById(@PathVariable Long id) { String url = "http://user-service/user/" + id; return restTemplate.getForObject(url, String.class); }
-
如果需要对整个Controller类编写默认fallback(必须无参),需要用@DefaultProperties注解:
@RestController @DefaultProperties(defaultFallback = "defaultFallback") public class ConsumerController { //省略其他方法 public String defaultFallback() { return "默认提示:对不起,网络太拥挤了!"; } }
-
如果需要更改Hystrix的默认超时时长(缺省1s),可以在yml配置文件里配置:
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 6000 #服务降级超时时间,默认1S