OpenFeign封装为springboot starter

简介: OpenFeign是什么随着业务的增多,我们的单体应用越来越复杂,单机已经难以满足性能的需求,这时候出现了分布式。分布式通讯除了RPC, REST HTTP请求是最简单的一种方式。OpenFeign是Netflix开源的参照Retrofit, JAXRS-2.0, and WebSocket的一个http client客户端,致力于减少http client客户端构建的复杂性。

OpenFeign是什么

随着业务的增多,我们的单体应用越来越复杂,单机已经难以满足性能的需求,这时候出现了分布式。分布式通讯除了RPC, REST HTTP请求是最简单的一种方式。OpenFeign是Netflix开源的参照Retrofit, JAXRS-2.0, and WebSocket的一个http client客户端,致力于减少http client客户端构建的复杂性。

官方用法

github提供了一个简单的demo,很容易理解。

interface GitHub {
  @RequestLine("GET /repos/{owner}/{repo}/contributors")
  List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}

static class Contributor {
  String login;
  int contributions;
}

public static void main(String... args) {
  GitHub github = Feign.builder()
                       .decoder(new GsonDecoder())
                       .target(GitHub.class, "https://api.github.com");

  // Fetch and print a list of the contributors to this library.
  List<Contributor> contributors = github.contributors("OpenFeign", "feign");
  for (Contributor contributor : contributors) {
    System.out.println(contributor.login + " (" + contributor.contributions + ")");
  }
}

简单的说,这么用没问题。但如果想要集成到系统中,关于Hystrix的配置还需要自己指定。为此,我单独把配置方案提炼了一下。

项目地址: https://github.com/Ryan-Miao/springboot-starter-feign

本项目提供了一个开箱即用的spring boot feign starter, 基于默认的约定配置
来简化和优化OpenFeign的使用流程.

How to use

引入repo

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

引入依赖

<dependency>
    <groupId>com.github.Ryan-Miao</groupId>
    <artifactId>springboot-starter-feign</artifactId>
    <version>1.1</version>
</dependency>

在springboot 项目中添加Configuration

@Autowired
private Environment environment;

@Bean
public FeignFactory feignFactory() {
    return new FeignFactory(environment, hystrixConfigurationProperties());
}

@Bean
public HystrixConfigurationProperties hystrixConfigurationProperties() {
    return new HystrixConfigurationProperties();
}

然后就可以使用了。

使用和配置

约定了一些配置,大概如下

feign:
  hystrixConfig:
    "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds": 8000
    "hystrix.command.GithubConnector#getRepos.execution.isolation.thread.timeoutInMilliseconds": 15000
  endpointConfig:
    GithubConnector:
      default:
        url: https://api.github.com
        readTimeoutMillis: 8000
        connectTimeoutMillis: 5000
      getRepos:
        url: https://api.github.com
        readTimeoutMillis: 15000
        connectTimeoutMillis: 10000
  • feign是配置的第一个索引
  • hystrixConfig是hystrix的配置,更多配置见Hystrix
  • endpointConfig是我们远程请求的host和超时配置,其中,第一个节点为Connector class
    的名称,下一个是具体到某个请求的key,整个Connector class的默认配置是default
    节点,如果该Connector里的某个请求的超时比较长,需要单独设置,则会覆盖默认节点。
    另外,hystrix的超时配置commankey为[connectorClassName][#][methodName]

定义一个GithubConnector,继承com.miao.connect.Connector

public interface GithubConnector extends Connector {

    @RequestLine("GET /users/{username}")
    @Headers({"Content-Type: application/json"})
    GithubUser getGithubUser(@Param("username") String username);

    @RequestLine("GET /users/{username}/repos")
    @Headers({"Content-Type: application/json"})
    Observable<String> getRepos(@Param("username") String username);
}

调用

@Autowired
private FeignFactory feignFactory;


@GetMapping("/profile/{username}")
public GithubUser getProfile(@PathVariable String username) {
    //采用Jackson作为编码和解码类库,url和超时配置按照default,即读取feign.endpointConfig.GithubConnector.default
    final GithubConnector connector = feignFactory.builder().getConnector(GithubConnector.class);
    return connector.getGithubUser(username);
}

@GetMapping("/repos/{username}")
public String getUserRepos(@PathVariable String username) {
    //用String来接收返回值, url和超时单独指定配置,因为请求时间较长
    //采用connector的method来当做获取配置的key,即读取feign.endpointConfig.GithubConnector.getRepos
    final GithubConnector connector = feignFactory.builder()
        .connectorMethod("getRepos")
        .stringDecoder()  //默认使用jackson作为序列化工具,这里接收string,使用StringDecoder
        .getConnector(GithubConnector.class);
    return connector.getRepos(username)
        .onErrorReturn(e -> {
            LOGGER.error("请求出错", e);
            Throwable cause = e.getCause();
            if (cause instanceof FeignErrorException) {
                throw (FeignErrorException) cause;
            }
            throw new RuntimeException("请求失败", e);
        }).toBlocking().first();
}

具体见使用示例example

相比原生有什么区别?

最大的区别是hystrix配置的内容,原生并没有提供hystrix相关配置,需要自己额外
准备。这里集成hystrix的约定,只要按照hystrix官方参数配置即可。

然后是缓存,在使用原生OpenFeign的过程中发现每次请求都要创建一个Connector,
而且Connector的创建又依赖一大堆别的class。对于我们远程调用比较频繁的应用来说,
增大了垃圾收集器的开销,我们其实不想回收。所以对Connector做了缓存。

其他用法同OpenFeign。

    关注我的公众号

img_acfe50023e4718b33064273d65e4cd67.jpe
唯有不断学习方能改变! -- Ryan Miao
目录
相关文章
|
Java Spring
Springboot starter开发之traceId请求日志链路追踪
能标识一次请求的完整流程,包括日志打印、响应标识等,以便于出现问题可以快速定位并解决问题。
1756 0
Springboot starter开发之traceId请求日志链路追踪
|
消息中间件 IDE Java
|
XML Java 程序员
保姆级教程,手把手教你实现SpringBoot自定义starter
保姆级教程,手把手教你实现SpringBoot自定义starter
8257 1
保姆级教程,手把手教你实现SpringBoot自定义starter
|
消息中间件 Java 微服务
还在用 OpenFeign?来试试 SpringBoot3 中的这个新玩意!
还在用 OpenFeign?来试试 SpringBoot3 中的这个新玩意!
1536 0
|
SpringCloudAlibaba NoSQL Java
1.1 w字,18 张图,彻底说透 springboot starter 机制
1.1 w字,18 张图,彻底说透 springboot starter 机制
765 1
1.1 w字,18 张图,彻底说透 springboot starter 机制
|
Java 程序员 网络安全
自定义spring boot starter三部曲之二:实战开发
《自定义spring boot starter三部曲》的第二篇,开始编码实战,开发并使用starter库
280 0
自定义spring boot starter三部曲之二:实战开发
|
NoSQL Java Redis
如何自定义一个SpringBoot中的starter
如何自定义一个SpringBoot中的starter
206 0
如何自定义一个SpringBoot中的starter
|
NoSQL Java 应用服务中间件
SpringBoot项目为什么需要引入大量的starter?如何自定义starter?
为什么我们在使用SpringBoot框架开发Java Web应用需要引入大量的starter?例如,我们引入Redis就在Maven中导入spring-boot-starter-data-redis。大家都知道SpringBoot的核心功能是自动装配,简化配置,我们通过starter实现SpringBoot自动装配的功能。那么我们如何去构建自己的starter呢?
299 0
|
NoSQL Java Redis
如何使用SpringBoot写一个属于自己的Starter
SpringBoot以其自动装配的能力被广泛应用,我们在写代码时肯定遇到过很多spring-boot-starter命名的依赖,比如spring-boot-starter-web,在pom文件中引入这些starter依赖后,SpringBoot就能通过自动装配的技术扫描到这些类并装载到Bean容器中。
|
Java 程序员 开发者
自定义spring boot starter三部曲之三:源码分析spring.factories加载过程
分析Spring和Spring boot源码,了解spring.factories自动加载原理
329 0
自定义spring boot starter三部曲之三:源码分析spring.factories加载过程