Spring Cloud 微服务之Feign(七)

22 篇文章 1 订阅
18 篇文章 0 订阅

一、什么是Spring Cloud Feign?

  • Spring Cloud OpenFeign 是声明式的服务调用工具,它整合了Ribbon和Hystrix,拥有负载均衡和服务容错功能。
  • Feign 使得我们只需创建一个接口并用注解的方式来配置它,就可以实现对某个服务接口的调用,简化了直接使用 RestTemplate 来调用服务接口的开发量。
  • Feign 具备可插拔的注解支持,同时支持Feign注解、JAX-RS注解及SpringMvc注解。
  • Feign 在使用时 Spring Cloud 集成了Ribbon和Eureka以提供负载均衡的服务调用及基于Hystrix的服务容错保护功能。

二、与Ribbon对比

  • 使用 Ribbon + RestTemplate 时,利用RestTemplate对Http请求的封装处理,形成了一套模板化的调用方法。
  • 使用 Feign 在此基础上做了进一步封装,由它来帮助我们定义和实现依赖服务接口的定义,在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它,现在是一个微服务接口上面标注一个Feign注解即可完成对服务提供方的接口绑定。
  • 利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡。
  • 利用Feign只需要定义服务绑定接口且以声明式的方法,优雅而且简单的实现了服务调用。

三、执行原理

  • 启动时,程序会进行包扫描,扫描所有包下所有@FeignClient注解的类,并将这些类注入到spring的IOC容器中。当定义的Feign中的接口被调用时,通过JDK的动态代理来生成RequestTemplate。
  • RequestTemplate中包含请求的所有信息,如请求参数,请求URL等。
  • RequestTemplate声场Request,然后将Request交给client处理,这个client默认是JDK的HTTPUrlConnection,也可以是OKhttp、Apache的HTTPClient等。
  • 最后client封装成LoadBaLanceClient,结合ribbon负载均衡地发起调用。

四、案例演示

  • 添加依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        <version>2.2.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
        <version>2.2.0.RELEASE</version>
    </dependency>
    
  • 添加配置

    • 启动类
    @SpringBootApplication
    @EnableEurekaClient
    @EnableDiscoveryClient
    @EnableFeignClients(basePackages = "com.jhy.feign.service")
    public class FeignClientApplication {
        public static void main(String[] args) {
            SpringApplication.run(FeignClientApplication.class, args);
        }
    }
    
    • 自定义配置类
    @Configuration
    public class FeignConfig {
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    
    • application.yml配置文件
    server.port=8080
    server.servlet.context-path=/
    spring.application.name=feign-client
    
    eureka.client.fetch-registry=true
    eureka.client.register-with-eureka=true 
    eureka.client.service-url.defaultZone: http://localhost:8010/eureka/
    
  • 添加服务

    • service

      @Component
      @FeignClient(value = "feign-service")
      public interface UserService {
      
          @GetMapping("/get/{id}")
          Map<String, Object> getUserById(@PathVariable Long id);
      
          @PostMapping("/add")
          Map<String, Object> addUser(@RequestBody User user);
      }
      
    • controller

      @RestController
      public class UserController {
      
          @Autowired
          private UserService userService;
      
          @GetMapping("/get/{id}")
          public Map<String, Object> getUser(@PathVariable Long id){
      
              return userService.getUserById(id);
          }
      
          @GetMapping("/add")
          public Map<String, Object> addUser(User user){
      
              return userService.addUser(user);
          }
      }
      
  • 测试使用

    多次访问:http://localhost:8080/get/1
    

    可以看到Feign默认采用轮询算法依次在每一个服务方进行访问

五、服务降级示例

利用Feign我们只需要为Feign客户端定义的业务接口添加一个服务降级处理的实现类即可

  • 修改配置

    # 修改application.yml文件(添加如下内容)
    
    feign:
      hystrix:
        enabled: true 
    
  • 添加实现类

    @Component
    public class UserFallbackService implements UserService {
    
        @Override
        public Map<String, Object> getUserById(Long id) {
            User user = new User(1L, "张三", "zhangsan");
    
            Map<String, Object> result = new HashMap<>();
            result.put("type", "ok");
            result.put("msg", "查询成功(fallback-service)");
            result.put("content", user);
    
            return result;
        }
    
        @Override
        public Map<String, Object> addUser(User user) {
            Map<String, Object> result = new HashMap<>();
    
            result.put("type", "ok");
            result.put("msg", "添加成功");
            result.put("content", user);
    
            return result;
        }
    }
    
  • 修改接口类

    @Component
    @FeignClient(value = "feign-service", fallback = UserFallbackService.class)
    public interface UserService {
    
        @GetMapping("/get/{id}")
        Map<String, Object> getUserById(@PathVariable Long id);
    
        @PostMapping("/add")
        Map<String, Object> addUser(@RequestBody User user);
    }
    
  • 测试使用

    关闭所有feign-service服务

    访问:http://localhost:8080/get/1
    

    发现服务接口调用的是我们服务降级编写的实现类

    在这里插入图片描述

六、开启日志打印

Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中HTTP请求的细节。

  • 日志级别

    • NONE:默认的,不显示任何日志
    • BASIC:仅记录请求方法、URL、响应状态码及执行时间
    • HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息
    • FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据
  • 添加配置

    • 配置类方式
    @Configuration
    public class FeignConfig {
        
        @Bean
        Logger.Level feignLoggerLevel() {
            return Logger.Level.FULL;
        }
    }
    
    • 配置文件方式
    # 修改application.yml文件(添加如下内容)
    
    logging:
      level:
        com.jhy.feign.service.UserService: debug
    
  • 测试使用

    访问:http://localhost:8080/get/1
    

    在这里插入图片描述

七、常用配置

feign:
  hystrix:
    #在Feign中开启Hystrix容错功能
    enabled: true 
  compression:
    request:
      #是否对请求进行GZIP压缩
      enabled: false 
      #指定压缩的请求数据类型
      mime-types: text/xml,application/xml,application/json 
      #超过该大小的请求会被压缩
      min-request-size: 2048 
    response:
      #是否对响应进行GZIP压缩
      enabled: false 
      
#修改日志级别
logging:
  level: 
    com.macro.cloud.service.UserService: debug

【源码地址】:GitHub

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程小吉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值