前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >客户端远程调用Feign

客户端远程调用Feign

作者头像
Isaac Zhang
发布2019-09-10 17:58:01
1.2K0
发布2019-09-10 17:58:01
举报

客户端远程调用

Feign

什么是Feign?

Feign是 Netflix 公司开源的声明式HTTP客户端

Github : Feign 源码

为什么需要Feign?

  1. 原代码可读性不高
  2. 复杂的URL难以维护(https://user-center/s?wd={userId}&rsv_spt=1&rsv_iqid=0x93bff3cd000cf3da&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=4&rsv_sug1=4&rsv_sug7=100&rsv_t=10c2risCimsUZC0RBruMerdnQRN1gRxFI%2BywuD0L3LwGGNd2dR8XE6x%2FyFOjHnR0oEi0&rsv_sug2=0&inputT=1535&rsv_sug4=1535&rsv_sug=2
  3. 难以应对需求的快速变化
  4. 编码体验和我们写JAVA差异较大

举例重构代码

                //替换前 
        ResponseEntity<UserDTO> userEntity = restTemplate.getForEntity(
                "http://user-center/users/{userId}",
                UserDTO.class, userId
        );
        UserDTO userDTO = new UserDTO();
        if (null != userEntity) {
            userDTO = userEntity.getBody();
            log.info("ShareService#findById userDTO: {}", userDTO);
        }
  1. 添加依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
  1. 启动类添加注解 @EnableFeignClients
  2. 添加配置
  3. 实现对应微服务的client
/**
 * IUserCenterFeignClient for 定义 user-center feign client
 *
 * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
 * @since 2019/7/15
 */
@FeignClient(name = "user-center")
public interface IUserCenterFeignClient {

    /**
     * Feign client 会将请求转换为
     * http://user-center/users/{userId}
     *
     * @param userId 用户id
     * @return 返回用户对象
     */
    @GetMapping(path = "/users/{userId}")
    public UserDTO findById(@PathVariable Long userId);
}
  1. 替换后代码
        //使用 FeignClient 来替换掉RestTemplate调用
        UserDTO userDTO = this.userCenterFeignClient.findById(userId);

Feign的组成

Feign的配置方式

Java Code
支持的配置项
自定义Feign日志级别
  • 级别内容
Demo

Tip : 有可能出现父子上下文重叠问题

  1. 在client添加配置
/**
 * IUserCenterFeignClient for 定义 user-center feign client
 *
 * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
 * @since 2019/7/15
 */
@FeignClient(name = "user-center",configuration = UserCenterFeignConfiguration.class)
public interface IUserCenterFeignClient {
   ...
}
  1. 编写java配置文件
/**
 * UserCenterFeignConfiguration for 自定义user-center服务请求中,feign的配置信息
 * {@link @Configuration} 不能添加该注解,否则会和ribbon一样,出现上下文重叠问题,造成配置全局共享
 * 如要添加该注解,需要将该类放在主程序启动扫描不到的包下
 *
 * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
 * @since 2019/7/15
 */
public class UserCenterFeignConfiguration {
    @Bean
    public Logger.Level level() {
        // 配置feign 日志级别,记录请求和响应的header、body以及元数据
        return Logger.Level.FULL;
    }
}
  1. 一定要在配置文件中添加该client 全路径 logging: level: #com.sxzhongf: debug com.sxzhongf.sharedcenter.feignclients.IUserCenterFeignClient: debug
  2. 打印信息
2019-07-15 15:06:11.650 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient           : [IUserCenterFeignClient#findById] <--- HTTP/1.1 200 (402ms)
2019-07-15 15:06:11.651 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient           : [IUserCenterFeignClient#findById] content-type: application/json;charset=UTF-8
2019-07-15 15:06:11.651 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient           : [IUserCenterFeignClient#findById] date: Mon, 15 Jul 2019 07:06:11 GMT
2019-07-15 15:06:11.651 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient           : [IUserCenterFeignClient#findById] transfer-encoding: chunked
2019-07-15 15:06:11.652 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient           : [IUserCenterFeignClient#findById] 
2019-07-15 15:06:11.652 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient           : [IUserCenterFeignClient#findById] {"id":1,"wxId":"","wxNickname":"IsaacZhang","roles":"","avatarUrl":"aaa","createTime":"2019-07-11T06:08:18.000+0000","updateTime":"2019-07-11T06:08:18.000+0000","bonus":100}
2019-07-15 15:06:11.652 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient           : [IUserCenterFeignClient#findById] <--- END HTTP (173-byte body)
Configuration
支持的配置项
demo

使用配置文件来定义log level

#logging:
  #level:
   #com.sxzhongf: debug
    #com.sxzhongf.sharedcenter.feignclients.IUserCenterFeignClient: debug
feign:
  client:
    config:
      user-center: #单服务配置
        loggerLevel: full
---        
feign:
  client:
    config:
      default: #全局配置日志级别
        loggerLevel: full

Feign的继承性

  • 官方不建议使用
  • 大多数公司使用?

架构师需要根据自身业务情况来决定,是否需要将不同的微服务进行业务耦合,还是使用冗余代码的方式来解放业务耦合性。

Feign多参请求

Get
  1. 使用@SpringQueryMap
@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {

    @GetMapping("/users/q")
    public UserDTO query(@SpringQueryMap UserDTO userDTO);
}
  1. 使用 @RequestParam
@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {

    @RequestMapping(value = "/users/q",method = RequestMethod.GET)
    public UserDTO query(@RequestParam("id") Long id,@RequestParam("name") String name);
}
  1. 使用Map构建,(不推荐)
@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {

    @RequestMapping(value = "/users/q",method = RequestMethod.GET)
    public UserDTO query(@RequestParam Map<String,Object> conditions);
}

注意:这种方式不建议使用。主要是因为可读性不好,而且如果参数为空的时候会有一些问题,例如map.put("username", null); 会导致user-center 服务接收到的username是"" ,而不是null。

Post

服务提供者方法

    @PostMapping("/create")
    public User createUser(@RequestBody User user){
        return null;
    }

服务调用者

@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {

    @RequestMapping(value = "/users/q",method = RequestMethod.POST)
    public UserDTO query(@RequestBody UserDTO user);
}

Feign脱离服务注册/Ribbon调用

@FeignClient(name = "xxxxx",url = "http://www.baidu.com")
public interface ITestBaiduFeignClient {

    @GetMapping("")
    public String getBaidu();
}

Feign 性能优化

使用连接池
httpClient
  1. 加依赖
        <!--Feign 性能优化,需要使用连接池,引入依赖-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
        </dependency>
  1. 加注解(不需要)
  2. 改配置
  httpclient:
    # 为feign启用 apache httpclient 做请求,而不使用默认的urlconection
    enabled: true
    # feign 最大连接数
    max-connections: 200
    # feign 单个路径请求的最大连接数
    max-connections-per-route: 50
okHttp
  1. 加依赖
        <!--Feign 性能优化,需要使用连接池,引入依赖-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
        </dependency>
  1. 加注解(不需要)
  2. 改配置
  httpclient:
    # 为feign启用 apache httpclient 做请求,而不使用默认的urlconection
    #enabled: true
    # feign 最大连接数
    max-connections: 200
    # feign 单个路径请求的最大连接数
    max-connections-per-route: 50
  okhttp:
    enabled: true
合理使用Feign日志

生产环境使用Logger.Level.BASIC

RestTemplate

RestTemplate VS. Feign

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-07-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 客户端远程调用
    • Feign
      • 什么是Feign?
      • 为什么需要Feign?
      • 举例重构代码
      • Feign的组成
      • Feign的配置方式
      • Feign的继承性
      • Feign多参请求
      • Feign脱离服务注册/Ribbon调用
      • Feign 性能优化
    • RestTemplate
      • RestTemplate VS. Feign
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档