在前面的学习中,我们使用了Ribbon的负载均衡功能,大大简化了远程调用时的代码:

  1. String url = "http://user-service/user/";
  2. User user = this.restTemplate.getForObject(url + id, User.class)

如果就学到这里,你可能以后需要编写类似的大量重复代码,格式基本相同,无非参数不一样。所以需要更优雅的方式,来对这些代码再次优化

1.简介

Feign翻译为伪装
Feign可以把Rest的请求进行隐藏,伪装成类似SpringMVC的Controller一样。你不用再自己拼接url,拼接参数等等操作,一切都交给Feign去做。
项目主页:https://github.com/OpenFeign/feign
05 Feign接口伪装 - 图1

2.快速入门

1) 导入依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-openfeign</artifactId>
  4. </dependency>

2) Feign客户端

  1. @FeignClient("user-service")
  2. public interface UserClient {
  3. @GetMapping("/user/{id}")
  4. User queryUserById(@PathVariable("id") Long id);
  5. }

● 首先这是一个接口,Feign会通过动态代理,帮我们生成实现类。这点跟mybatis的mapper很像
● @FeignClient,声明这是一个Feign客户端,类似@Mapper注解。同时通过value属性指定服务名称
● 接口中的定义方法,完全采用SpringMVC的注解,Feign会根据注解帮我们生成URL,并访问获取结果
改造原来的调用逻辑 ConsumerController

  1. @Autowired
  2. private UserClient userClient;
  3. @GetMapping("feign/{id}")
  4. public User queryById4(@PathVariable("id") Long id) {
  5. return userClient.queryById(id);
  6. }

2) 开启Feign功能

我们在启动类上,添加注解,开启Feign功能

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. @EnableFeignClients // 开启Feign功能
  4. public class ConsumerApplication {
  5. public static void main(String[] args) {
  6. SpringApplication.run(ConsumerApplication.class, args);
  7. }
  8. }

RestTemplate的注册已经删除了。Feign中已经自动集成了Ribbon负载均衡,因此我们不需要自己定义RestTemplate了

4) 启动测试

05 Feign接口伪装 - 图2

3.负载均衡

Feign中本身已经集成了Ribbon依赖和自动配置:
05 Feign接口伪装 - 图3
因此我们不需要额外引入依赖,也不需要再注册RestTemplate对象。
另外,我们可以像上节课中讲的那样去配置Ribbon,可以通过ribbon.xx来进行全局配置。也可以通过服务名.ribbon.xx来对指定服务配置:

  1. user-service:
  2. ribbon:
  3. ConnectTimeout: 250 # 连接超时时间(ms)
  4. ReadTimeout: 1000 # 通信超时时间(ms)
  5. OkToRetryOnAllOperations: true # 是否对所有操作重试
  6. MaxAutoRetriesNextServer: 1 # 同一服务不同实例的重试次数
  7. MaxAutoRetries: 1 # 同一实例的重试次数

4.Hystrix支持

Feign默认也有对Hystrix的集成:
05 Feign接口伪装 - 图4
只不过,默认请款下是关闭的,我们需要通过下面的参数来开启

  1. feign:
  2. hystrix:
  3. enabled: true # 开启Feign的熔断功能

但是,Feign中的Fallback配置不像Rebbon那样简单了

  1. 首先,定义一个类,并实现UserClient
    1. @Component
    2. public class UserClientFallback implements UserClient {
    3. @Override
    4. public User queryById(Long id) {
    5. User user = new User();
    6. user.setName("未知用户!");
    7. return user;
    8. }
    9. }
    2.然后在UserClient中,指定Fallback类
    1. @FeignClient(value = "user-service",fallback = UserClientFallback.class)
    2. public interface UserClient {
    3. @GetMapping("user/{id}")
    4. User queryById(@PathVariable("id") Long id);
    5. }
    3.重启测试
    将user-service服务关闭; 熔断生效
    05 Feign接口伪装 - 图5