• 3.【Spring Cloud Alibaba】声明式HTTP客户端-Feign


    使用Feign实现远程HTTP调用

    什么是Feign

    实现
    pom.xml
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-httpclient</artifactId>
    </dependency>
    
    @MapperScan("com.itmuch.contentcenter.dao")
    @SpringBootApplication
    @EnableFeignClients// (defaultConfiguration = GlobalFeignConfiguration.class)
    @EnableBinding({Source.class})
    public class ContentCenterApplication {
    
    @FeignClient(name = "user-center")
    public interface UserCenterFeignClient {
        /**
         * http://user-center/users/{id}
         *
         * @param id
         * @return
         */
        @GetMapping("/users/{id}")
        UserDTO findById(@PathVariable Integer id);
    }
    
    private final UserCenterFeignClient userCenterFeignClient;
    
    // 1. 代码不可读
    // 2. 复杂的url难以维护:https://user-center/s?ie={ie}&f={f}&rsv_bp=1&rsv_idx=1&tn=baidu&wd=a&rsv_pq=c86459bd002cfbaa&rsv_t=edb19hb%2BvO%2BTySu8dtmbl%2F9dCK%2FIgdyUX%2BxuFYuE0G08aHH5FkeP3n3BXxw&rqlang=cn&rsv_enter=1&rsv_sug3=1&rsv_sug2=0&inputT=611&rsv_sug4=611
    // 3. 难以相应需求的变化,变化很没有幸福感
    // 4. 编程体验不统一
    UserDTO userDTO = this.userCenterFeignClient.findById(userId);
    

    Feign的组成

    image

    细粒度配置自定义

    • Java代码方式
    • 配置属性方法

    指定日志级别

    image

    Java代码方式

    UserCenterFeignClient
    @FeignClient(name = "user-center", configuration = GlobalFeignConfiguration.class)
    public interface UserCenterFeignClient {
        /**
         * http://user-center/users/{id}
         *
         * @param id
         * @return
         */
        @GetMapping("/users/{id}")
        UserDTO findById(@PathVariable Integer id);
    }
    
    GlobalFeignConfiguration
    /**
     * feign的配置类
     * 这个类别加@Configuration注解了,否则必须挪到@ComponentScan能扫描的包以外
     */
    public class GlobalFeignConfiguration {
        @Bean
        public Logger.Level level(){
            // 让feign打印所有请求的细节
            return Logger.Level.FULL;
        }
    }
    
    application.yml
    logging:
      level:
        com.itmuch.contentcenter.feignclient.UserCenterFeignClient: debug
    

    配置属性方法

    image

    image

    全局配置

    • Java代码方式
    • 配置属性方式

    Java代码方式

    ContentCenterApplication

    EnableFeignClients

    // 扫描mybatis哪些包里面的接口
    @MapperScan("com.itmuch.contentcenter.dao")
    @SpringBootApplication
    @EnableFeignClients(defaultConfiguration = GlobalFeignConfiguration.class)
    @EnableBinding({Source.class})
    public class ContentCenterApplication {
    
    /**
     * feign的配置类
     * 这个类别加@Configuration注解了,否则必须挪到@ComponentScan能扫描的包以外
     */
    public class GlobalFeignConfiguration {
        @Bean
        public Logger.Level level(){
            // 让feign打印所有请求的细节
            return Logger.Level.FULL;
        }
    }
    

    配置属性方式

    // 扫描mybatis哪些包里面的接口
    @MapperScan("com.itmuch.contentcenter.dao")
    @SpringBootApplication
    @EnableFeignClients// (defaultConfiguration = GlobalFeignConfiguration.class)
    @EnableBinding({Source.class})
    public class ContentCenterApplication {
    

    image

    支持的配置项

    Java代码方式支持的配置项

    image

    配置属性方式支持的配置项

    image

    配置最佳实践

    Ribbon配置 VS Feign配置

    image

    Feign代码方式 vs 属性方式

    image

    最佳实践

    image

    Feign的继承

    关于继承的争议

    • 官方观点:官方不推荐使用
    • 业界观点:很多公司使用
    • 个人观点:权衡利弊

    多参数请求构造

    Get请求

    TestController
    @GetMapping("test-get")
    public UserDTO query(UserDTO userDTO) {
        return testUserCenterFeignClient.query(userDTO);
    }
    

    方法1

    TestUserCenterFeignClient
    import com.itmuch.contentcenter.domain.dto.user.UserDTO;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.cloud.openfeign.SpringQueryMap;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @FeignClient(name = "user-center")
    public interface TestUserCenterFeignClient {
        @GetMapping("/q")
        UserDTO query(@SpringQueryMap UserDTO userDTO);
    }
    

    方法二

    @FeignClient(name = "user-center")
    public interface UserFeignClient {
      @RequestMapping(value = "/q", method = RequestMethod.GET)
      public UserDTO query(@RequestParam("id") Long id, @RequestParam("username") String username);
    }
    

    POST请求包含多个参数

    下面来讨论如何使用Feign构造包含多个参数的POST请求。假设服务提供者的Controller是这样编写的:

    @RestController
    public class UserController {
      @PostMapping("/post")
      public User post(@RequestBody User user) {
        ...
      }
    }
    
    我们要如何使用Feign去请求呢?答案非常简单,示例:
    @FeignClient(name = "microservice-provider-user")
    public interface UserFeignClient {
      @RequestMapping(value = "/post", method = RequestMethod.POST)
      public User post(@RequestBody User user);
    }
    

    Feign脱离Ribbon的使用

    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    
    // 脱离ribbon的使用
    @FeignClient(name = "baidu", url = "http://www.baidu.com")
    public interface TestBaiduFeignClient {
        @GetMapping("")
        String index();
    }
    

    RestTemplate vs Feign

    image

    Feign性能优化

    • 连接池[提升15%左右]
    feign:
      sentinel:
    
        # 为feign整合sentinel
        enabled: true
      client:
        config:
          # 全局配置
          default:
            loggerLevel: full
            requestInterceptors:
              - com.itmuch.contentcenter.feignclient.interceptor.TokenRelayRequestIntecepor
      httpclient:
        # 让feign使用apache httpclient做请求;而不是默认的urlconnection
        enabled: true
        # feign的最大连接数
        max-connections: 200
        # feign单个路径的最大连接数
        max-connections-per-route: 50
    
    目前,在Spring cloud中服务之间通过restful方式调用有两种方式
    • restTemplate+Ribbon
    • feign

    从实践上看,采用feign的方式更优雅(feign内部也使用了ribbon做负载均衡)。

  • 相关阅读:
    linux之uniq
    shell之sort
    tr命令的使用
    AWK 简明教程
    Word Frequency
    10亿个数中选出最大的100个数
    代理模式(也称委托模式)
    java内存相关
    Two Sum
    Java的集合
  • 原文地址:https://www.cnblogs.com/xjknight/p/12349099.html
Copyright © 2020-2023  润新知