• SpringCloud 学习笔记5


    Feign

    在前面的学习中(SpringCloud 学习笔记1),使用了Ribbon的负载均衡功能,大大简化了远程调用时的代码:

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

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

    这就是我们接下来要学的Feign的功能了。


    简介

    • Feign是从Netflix中分离出来的轻量级项目,能够在类接口上添加注释,成为一个REST API 客户端。
    • Feign中对 Hystrix 有依赖关系。Feign只是一个便利的rest框架,简化调用,最后还是通过Ribbon(负载均衡)在注册服务器(如Eureka)中找到服务实例,然后对请求进行分配。
    • Feign可以把Rest的请求进行隐藏,伪装成类似SpringMVC的Controller一样。你不用再自己拼接url,拼接参数等等操作,一切都交给Feign去做。

    项目主页:https://github.com/OpenFeign/feign

    20200821120439

    快速入门

    导入依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
        <version>2.0.1.RELEASE</version>
    </dependency>
    

    Feign 的客户端

    // 服务名称:user-service
    @FeignClient("user-service")
    public interface UserClient {
        /**
         * 请求参数 id、请求路径 user、返回对象
         * @param id 请求参数
         * @return User
         */
        @GetMapping("/user/{id}")
        User queryById(@PathVariable("id") Long id);
    }
    

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

    改造原来的调用逻辑:

    @RestController
    @DefaultProperties
    @RequestMapping(value = "consumer")
    public class ConsumerController {
    
        @Autowrited
        private UserClient userClient;
        
        private static final Logger logger = LoggerFactory.getLogger(ConsumerController.class);
        
        @HystrixCommand(fallbackMethod = "queryByIdFallback")
        @GetMapping("{id}")
        public String queryById(@PathVariable(value = "id") Long id) {
            return userClient.queryById(id).toString();
        }
        
        public String queryByIdFallback(Long id) {
            logger.error("查询用户信息失败,id: {}", id);
            return "不好意思,服务器正忙!";
        }
    }
    

    开启Feign功能

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

    @EnableCircuitBreaker
    @SpringBootApplication
    @EnableDiscoveryClient // 开启Eureka客户端
    @EnableFeignClients  // 开启 Feign 功能
    public class ConsumerApplication {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class);
        }
    }
    

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


    启动测试:

    访问接口:http://localhost:8080/consumer/13

    {"id":13,"userName":"LeeHua","password":"123456","name":"李华","age":21,"sex":1,"birthday":"1998-10-24T16:00:00.000+0000","created":"2018-08-30T16:00:00.000+0000","updated":"2020-09-03T16:00:00.000+0000","note":"测试"}
    

    负载均衡

    Feign中本身已经集成了Ribbon依赖和自动配置:

    20200821144420

    因此我们不需要额外引入依赖,也不需要再注册RestTemplate对象。

    另外,我们可以这样样来配置Ribbon

    1. 可以通过ribbon.xx来进行全局配置。
    2. 也可以通过服务名.ribbon.xx来对指定服务配置:
    user-service:
      ribbon:
        ConnectTimeout: 250 # 连接超时时间(ms)
        ReadTimeout: 1000 # 通信超时时间(ms)
        OkToRetryOnAllOperations: true # 是否对所有操作重试
        MaxAutoRetriesNextServer: 1 # 同一服务不同实例的重试次数
        MaxAutoRetries: 1 # 同一实例的重试次数
    

    Hystix支持

    Feign默认也有对Hystix的集成:

    20200821145543

    只不过,默认情况下是关闭的。我们需要通过下面的参数来开启:

    feign:
      hystrix:
        enabled: true # 开启Feign的熔断功能
    

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

    1)首先,我们要定义一个类,实现刚才编写的UserClient,作为fallback的处理类

    @Component
    public class UserClientFallback implements UserClient {
        @Override
        public User queryById(Long id) {
            User user = new User();
            user.setName("未知用户!!!");
            return user;
        }
    }
    

    2)然后在UserFeignClient中,指定刚才编写的实现类

    // 服务名称:user-service
    // fallback:UserClientFallback
    @FeignClient(value = "user-service", fallback = UserClientFallback.class)
    public interface UserClient {
        /**
         * 请求参数 id、请求路径 user、返回对象
         * @param id 请求参数
         * @return User
         */
        @GetMapping("/user/{id}")
        User queryById(@PathVariable("id") Long id);
    }
    

    3)重启测试:

    我们关闭user-service服务,然后在页面访问:http://localhost:8080/consumer/13

    {"id":13,"userName":null,"password":null,"name":"未知用户","age":null,"sex":null,"birthday":null,"created":null,"updated":null,"note":null}
    

    请求压缩(了解)

    Spring Cloud Feign 支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。通过下面的参数即可开启请求与响应的压缩功能:

    feign:
      compression:
        request:
          enabled: true # 开启请求压缩
        response:
          enabled: true # 开启响应压缩
    

    同时,我们也可以对请求的数据类型,以及触发压缩的大小下限进行设置:

    feign:
      compression:
        request:
          enabled: true # 开启请求压缩
          mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
          min-request-size: 2048 # 设置触发压缩的大小下限
    

    注:上面的数据类型、压缩大小下限均为默认值。


    日志级别(了解)

    前面讲过,通过logging.level.xx=debug来设置日志级别。然而这个对Fegin客户端而言不会产生效果。因为@FeignClient注解修改的客户端在被代理时,都会创建一个新的Fegin.Logger实例。我们需要额外指定这个日志的级别才可以。


    1)设置pres.stringbug包下的日志级别都为debug

    logging:
      level:
        com.leyou: debug
    

    2)编写配置类,定义日志级别

    @Configuration
    public class FeignConfig {
        @Bean
        Logger.Level feignLoggerLevel(){
            return Logger.Level.FULL;
        }
    }
    

    这里指定的Level级别是FULL,Feign支持4种级别:

    20200821152514
    • NONE:不记录任何日志信息,这是默认值。
    • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
    • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
    • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。

    3)在FeignClient中指定配置类:

    @FeignClient(value = "user-service", fallback = UserClientFallback.class, configuration = FeignConfig.class)
    public interface UserFeignClient {
        @GetMapping("/user/{id}")
        User queryUserById(@PathVariable("id") Long id);
    }
    

    4)重启项目,即可看到每次访问的日志:

    20200821152617
    Good Good Write Bug, Day Day Up
  • 相关阅读:
    POJ 1003 解题报告
    POJ 1004 解题报告
    POJ-1002 解题报告
    vi--文本编辑常用快捷键之光标移动
    常用图表工具
    September 05th 2017 Week 36th Tuesday
    September 04th 2017 Week 36th Monday
    September 03rd 2017 Week 36th Sunday
    September 02nd 2017 Week 35th Saturday
    September 01st 2017 Week 35th Friday
  • 原文地址:https://www.cnblogs.com/liyihua/p/14482644.html
Copyright © 2020-2023  润新知