zoukankan      html  css  js  c++  java
  • OpenFeign封装为springboot starter

    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。

  • 相关阅读:
    SpringBoot-容器启动的时候执行一些内容
    Java JVM 启动参数
    leecode刷题(9)-- 有效的数独
    leecode刷题(8)-- 两数之和
    leecode刷题(7)-- 加一
    leecode刷题(6)-- 两个数组的交集II
    leecode刷题(5)-- 只出现一次的数字
    leecode刷题(4)-- 存在重复数组
    leecode刷题(3)-- 旋转数组
    leecode刷题(2)-- 买卖股票的最佳时机
  • 原文地址:https://www.cnblogs.com/woshimrf/p/springboot-with-feign.html
Copyright © 2011-2022 走看看