OpenFeign是什么 随着业务的增多,我们的单体应用越来越复杂,单机已经难以满足性能的需求,这时候出现了分布式。分布式通讯除了RPC, REST HTTP请求是最简单的一种方式。OpenFeign 是Netflix开源的参照Retrofit, JAXRS-2.0, and WebSocket的一个http client客户端,致力于减少http client客户端构建的复杂性。
官方用法 github提供了一个简单的demo,很容易理解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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" ); 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
1 2 3 4 5 6 <repositories > <repository > <id > jitpack.io</id > <url > https://jitpack.io</url > </repository > </repositories >
引入依赖
1 2 3 4 5 <dependency > <groupId > com.github.Ryan-Miao</groupId > <artifactId > springboot-starter-feign</artifactId > <version > 1.1</version > </dependency >
在springboot 项目中添加Configuration
1 2 3 4 5 6 7 8 9 10 11 12 @Autowired private Environment environment;@Bean public FeignFactory feignFactory () { return new FeignFactory(environment, hystrixConfigurationProperties()); } @Bean public HystrixConfigurationProperties hystrixConfigurationProperties () { return new HystrixConfigurationProperties(); }
然后就可以使用了。
使用和配置 约定了一些配置,大概如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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
1 2 3 4 5 6 7 8 9 10 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) ; }
调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @Autowired private FeignFactory feignFactory;@GetMapping("/profile/{username}") public GithubUser getProfile (@PathVariable String username) { final GithubConnector connector = feignFactory.builder().getConnector(GithubConnector.class); return connector.getGithubUser(username); } @GetMapping("/repos/{username}") public String getUserRepos (@PathVariable String username) { final GithubConnector connector = feignFactory.builder() .connectorMethod("getRepos" ) .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。