zoukankan      html  css  js  c++  java
  • 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做负载均衡)。

  • 相关阅读:
    Bootstrap 2.2.2 的新特性
    Apache POI 3.9 发布,性能显著提升
    SQL Relay 0.48 发布,数据库中继器
    ProjectForge 4.2.0 发布,项目管理系统
    红帽企业 Linux 发布 6.4 Beta 版本
    红薯 快速的 MySQL 本地和远程密码破解
    MariaDB 宣布成立基金会
    Percona XtraBackup 2.0.4 发布
    Rocks 6.1 发布,光盘机群解决方案
    精通Servlet研究,HttpServlet的实现追究
  • 原文地址:https://www.cnblogs.com/xjknight/p/12349099.html
Copyright © 2011-2022 走看看