专栏目录
31. FeignClient 实现断路器以及线程隔离限流的思路 15.UnderTow 订制 19.Eureka的服务端设计与配置 5.所有项目的parent与spring-framework-common说明 16.Eureka架构和核心概念 36. 验证断路器正确性 28.OpenFeign的生命周期-进行调用 4.maven依赖回顾以及项目框架结构 40. spock 单元测试封装的 WebClient(上) 38. 实现自定义 WebClient 的 NamedContextFactory 37. 实现异步的客户端封装配置管理的意义与设计 1. 背景 35. 验证线程隔离正确性 29.Spring Cloud OpenFeign 的解析(1) 41. SpringCloudGateway 基本流程讲解(2) 44.避免链路信息丢失做的设计(1) 14.UnderTow AccessLog 配置介绍 40. spock 单元测试封装的 WebClient(下) 17.Eureka的实例配置 7.从Bean到SpringCloud 6.微服务特性相关的依赖说明 12.UnderTow 简介与内部原理 11.Log4j2 监控相关 21.Spring Cloud LoadBalancer简介 20. 启动一个 Eureka Server 集群 23.订制Spring Cloud LoadBalancer 22.Spring Cloud LoadBalancer核心源码 30. FeignClient 实现重试 24.测试Spring Cloud LoadBalancer 8.理解 NamedContextFactory 43.为何 SpringCloudGateway 中会有链路信息丢失 41. SpringCloudGateway 基本流程讲解(1) 39. 改造 resilience4j 粘合 WebClient 44.避免链路信息丢失做的设计(2) 18.Eureka的客户端核心设计和配置 27.OpenFeign的生命周期-创建代理 25.OpenFeign简介与使用 42.SpringCloudGateway 现有的可供分析的请求日志以及缺陷 10.使用Log4j2以及一些核心配置 26.OpenFeign的组件 33. 实现重试、断路器以及线程隔离源码 13.UnderTow 核心配置 32. 改进负载均衡算法 3.Eureka Server 与 API 网关要考虑的问题 45. 实现公共日志记录 2.微服务框架需要考虑的问题 9.如何理解并定制一个Spring Cloud组件 34.验证重试配置正确性

25.OpenFeign简介与使用

干货满满张哈希
• 阅读 1093

25.OpenFeign简介与使用

本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent

OpenFeign 的由来和实现思路

在微服务系统中,我们经常会进行 RPC 调用。在 Spring Cloud 体系中,RPC 调用一般就是 HTTP 协议的调用。对于每次调用,基本都要经过如下步骤:

  • 找到微服务实例列表并选择一个实例
  • 调用参数序列化
  • 使用 Http 客户端将请求发送出去
  • 响应处理,反序列化等等 除了这些公共逻辑,业务上只需要定义参数,HTTP 方法,HTTP URI,响应就可以,也就是使用接口就能定义:
    interface HttpBin {
     @Get(uri = "/get")
     String get(@Param("param") String param);
    }
    例如上面这个接口,就定义了一个 HTTP 请求,HTTP 方法为 GET,路径是 /get,参数是 param,响应为 String类型。之后只要定义好公共逻辑,就能使用这个接口进行调用了。

对于这些公共逻辑的实现设计,我们很自然的就能想到切面与动态代理。之前的章节,我们提到过 JDK 中有针对接口的动态代理,其实就是实现 java.lang.reflect.InvocationHandler 然后针对这个接口实现代理类。之后使用这个代理类进行调用即可走入 InvocationHandler 中定义的逻辑。

以上,就是 OpenFeign 的设计实现思路与用途

OpenFeign 简介

OpenFeign 是一个基于声明式(通过类元数据定义,例如注解等)定义的 HTTP 请求客户端。这个库可以让你通过注解来自动生成调用对应 HTTP 服务的客户端,从代码上看调用这个远程服务和调用本地服务方法一样。OpenFeign 支持多种 HTTP 注解,包括 Feign 注解和 JAX-RS 注解,并且可以通过配置类似于插件的形式支持不同种类的注解。同时,还可以配置编码器,解码器,来编码请求并解码响应。底层的 HTTP Client 也是可以配置的,你可以使用 Java 原生的 Http 链接,也可以使用 Apache HttpClient 还有 OkHttpClient 等等。

目前 OpenFeign 还在不断迭代更新中,可以通过这个链接查看当前的 RoadMap。当前我们使用的是 OpenFeign 11,当前实现中或者计划中的特性包括:

  • 响应缓存,支持进程内或者跨进程响应缓存(实现中)
  • 实现更完善的 URI 模板支持(实现中)
  • 重构 Logger 日志 API(实现中)
  • 重构 Retry 重试 API(实现中)
  • 采集指标相关 API(下一步要实现)
  • 通过 CompletableFuture 作为基础类,实现异步 API(当前已经有基本实现,下一步完整实现)
  • 响应式 API (下一步要实现)
  • 断路器相关支持(计划中)

OpenFeign 基本使用

我们先来看 OpenFeign 的使用,先不关心 Spring Cloud 环境下如何使用,这样更能理解其底层原理。单独使用 OpenFeign 分以下几步:

  1. 定义远程 HTTP 调用 API 接口
  2. 创建 Feign 代理的 HTTP 调用接口实现
  3. 使用代理类进行调用

具体例子是:

interface GitHub {
    /**
     * 定义get方法,包括路径参数,响应返回序列化类
     * @param owner
     * @param repository
     * @return
     */
    @RequestLine("GET /repos/{owner}/{repo}/contributors")
    List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repository);

    /**
     * 响应体结构类
     */
    class Contributor {
        String login;
        int contributions;

        public Contributor() {
        }

        public String getLogin() {
            return login;
        }

        public void setLogin(String login) {
            this.login = login;
        }

        public int getContributions() {
            return contributions;
        }

        public void setContributions(int contributions) {
            this.contributions = contributions;
        }
    }
}

public static void main(String[] args) {
    //创建 Feign 代理的 HTTP 调用接口实现
    GitHub github = Feign.builder()
                        //指定解码器为 FastJsonDecoder
                        .decoder(new FastJsonDecoder())
                        //指定代理类为 GitHub,基址为 https://api.github.com
                        .target(GitHub.class, "https://api.github.com");
    List<GitHub.Contributor> contributors = github.contributors("OpenFeign", "feign");
}


/**
 * 基于 FastJson 的反序列化解码器
 */
static class FastJsonDecoder implements Decoder {
    @Override
    public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
        //读取 body
        byte[] body = response.body().asInputStream().readAllBytes();
        return JSON.parseObject(body, type);
    }
}

在上面这个例子中,我们定义了访问 GET https://api.github.com/repos/{owner}/{repo}/contributors 这个接口的 OpenFeign 客户端,并自定义了响应解码器,反序列化了响应体。这就是 OpenFeign 的基本使用。

25.OpenFeign简介与使用

我们这一节详细介绍了 OpenFeign 的设计思路以及 RoadMap,了解这些之后,我们再来详细分析 Openfeign,就能理解其中的一些设计以及使用思路了。并且某些重构中的特性,我们在使用中需要格外注意,不过也不必担心,因为在 Spring Cloud 中使用 OpenFeign 的特性都是通过加入胶水项目依赖实现的,底层 API 重构是胶水项目需要关心的事情。

微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer

25.OpenFeign简介与使用

点赞
收藏
评论区
推荐文章

暂无数据