5、Spring Cloud-声明式调用 Feign(下)
5.5、在Feign中使用HttpClient和OkhHttp
FeignRibbonClientAutoConfiguration.java
@ConditionalOnClass({ILoadBalancer.class, Feign.class})
@Configuration
@AutoConfigureBefore({FeignAutoConfiguration.class})
@EnableConfigurationProperties({FeignHttpClientProperties.class})
@Import({HttpClientFeignLoadBalancedConfiguration.class, OkHttpFeignLoadBalancedConfiguration.class, DefaultFeignLoadBalancedConfiguration.class})
public class FeignRibbonClientAutoConfiguration {
public FeignRibbonClientAutoConfiguration() {
}
@Bean
@Primary
@ConditionalOnMissingBean
@ConditionalOnMissingClass({"org.springframework.retry.support.RetryTemplate"})
public CachingSpringLoadBalancerFactory cachingLBClientFactory(SpringClientFactory factory) {
return new CachingSpringLoadBalancerFactory(factory);
}
@Bean
@Primary
@ConditionalOnMissingBean
@ConditionalOnClass(
name = {"org.springframework.retry.support.RetryTemplate"}
)
public CachingSpringLoadBalancerFactory retryabeCachingLBClientFactory(SpringClientFactory factory, LoadBalancedRetryFactory retryFactory) {
return new CachingSpringLoadBalancerFactory(factory, retryFactory);
}
@Bean
@ConditionalOnMissingBean
public Options feignRequestOptions() {
return LoadBalancerFeignClient.DEFAULT_OPTIONS;
}
}
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
配置文件中:
feign.httpclient.enabled=true
从新启动即可(具体看源码进行分析)

5.6、Feign如何实现负载均衡
LoadBalancerFeignClient.java
public Response execute(Request request, Options options) throws IOException {
try {
URI asUri = URI.create(request.url());
String clientName = asUri.getHost();
URI uriWithoutHost = cleanUrl(request.url(), clientName);
RibbonRequest ribbonRequest = new RibbonRequest(this.delegate, request, uriWithoutHost);
IClientConfig requestConfig = this.getClientConfig(options, clientName);
return ((RibbonResponse)this.lbClient(clientName).executeWithLoadBalancer(ribbonRequest, requestConfig)).toResponse();
} catch (ClientException var8) {
IOException io = this.findIOException(var8);
if (io != null) {
throw io;
} else {
throw new RuntimeException(var8);
}
}
}
execute执行请求的方法
public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException {
LoadBalancerCommand command = this.buildLoadBalancerCommand(request, requestConfig);
try {
return (IResponse)command.submit(new ServerOperation<T>() {
public Observable<T> call(Server server) {
URI finalUri = AbstractLoadBalancerAwareClient.this.reconstructURIWithServer(server, request.getUri());
ClientRequest requestForServer = request.replaceUri(finalUri);
try {
return Observable.just(AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig));
} catch (Exception var5) {
return Observable.error(var5);
}
}
}).toBlocking().single();
} catch (Exception var6) {
Throwable t = var6.getCause();
if (t instanceof ClientException) {
throw (ClientException)t;
} else {
throw new ClientException(var6);
}
}
}
public Observable<T> submit(final ServerOperation<T> operation) {
final LoadBalancerCommand<T>.ExecutionInfoContext context = new LoadBalancerCommand.ExecutionInfoContext();
if (this.listenerInvoker != null) {
try {
this.listenerInvoker.onExecutionStart();
} catch (AbortExecutionException var6) {
return Observable.error(var6);
}
}
final int maxRetrysSame = this.retryHandler.getMaxRetriesOnSameServer();
final int maxRetrysNext = this.retryHandler.getMaxRetriesOnNextServer();
Observable<T> o = (this.server == null ? this.selectServer() : Observable.just(this.server)).concatMap(new Func1<Server, Observable<T>>() {
public Observable<T> call(Server server) {
context.setServer(server);
......
上述代码中有一个selectServe()方法:该方法就是选择服务进行负载均衡的方法
private Observable<Server> selectServer() {
return Observable.create(new OnSubscribe<Server>() {
public void call(Subscriber<? super Server> next) {
try {
Server server = LoadBalancerCommand.this.loadBalancerContext.getServerFromLoadBalancer(LoadBalancerCommand.this.loadBalancerURI, LoadBalancerCommand.this.loadBalancerKey);
next.onNext(server);
next.onCompleted();
} catch (Exception var3) {
next.onError(var3);
}
}
});
}
由上述可知,最终负载均衡交给loadbalancerContext来处理

5.7、总结
5、Spring Cloud-声明式调用 Feign(下)的更多相关文章
- spring cloud服务间调用feign
参考文章:Spring Cloud Feign设计原理 1.feign是spring cloud服务间相互调用的组件,声明式.模板化的HTTP客户端.类似的HttpURLConnection.Apac ...
- Spring Cloud声明式调用Feign负载均衡FeignClient详解
为了深入理解Feign,下面将从源码的角度来讲解Feign.首先来看看FeignClient注解@FeignClient的源码,代码如下: FeignClient注解被@Target(ElementT ...
- spring cloud 2.x版本 Feign服务发现教程(内含集成Hystrix熔断机制)
前言 本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server和eureka-client的实现. 参考 ...
- Spring-Cloud之Feign声明式调用-4
一.Feign受Retrofit.JAXRS-2.0和WebSocket影响,采用了声明式API 接口的风格,将Java Http 客户端绑定到它的内部. Feign 首要目的是将 Java Http ...
- Spring Cloud项目中通过Feign进行内部服务调用发生401\407错误无返回信息的问题
问题描述 最近在使用Spring Cloud改造现有服务的工作中,在内部服务的调用方式上选择了Feign组件,由于服务与服务之间有权限控制,发现通过Feign来进行调用时如果发生了401.407错误时 ...
- 【spring cloud】spring cloud2.X spring boot2.0.4调用feign配置Hystrix Dashboard 和 集成Turbine 【解决:Hystrix仪表盘Unable to connect to Command Metric Stream】【解决:Hystrix仪表盘Loading...】
环境: <java.version>1.8</java.version><spring-boot.version>2.0.4.RELEASE</spring- ...
- Spring Cloud系列之使用Feign进行服务调用
在上一章的学习中,我们知道了微服务的基本概念,知道怎么基于Ribbon+restTemplate的方式实现服务调用,接着上篇博客,我们学习怎么基于Feign实现服务调用,请先学习上篇博客,然后再学习本 ...
- Spring Cloud Alibaba Sentinel 整合 Feign 的设计实现
作者 | Spring Cloud Alibaba 高级开发工程师洛夜 来自公众号阿里巴巴中间件投稿 前段时间 Hystrix 宣布不再维护之后(Hystrix 停止开发...Spring Cloud ...
- Spring Cloud系列文,Feign整合Ribbon和Hysrix
在本博客之前的Spring Cloud系列里,我们讲述了Feign的基本用法,这里我们将讲述下Feign整合Ribbon实现负载均衡以及整合Hystrix实现断路保护效果的方式. 1 准备Eureka ...
- Spring Cloud Alibaba Sentinel对Feign的支持
Spring Cloud Alibaba Sentinel 除了对 RestTemplate 做了支持,同样对于 Feign 也做了支持,如果我们要从 Hystrix 切换到 Sentinel 是非常 ...
随机推荐
- java四则运算----前缀、中缀、后缀表达式
接到一个新需求,需要实现可配置公式,然后按公式实现四则运算. 刚拿到需求,第一反应就是用正则匹配‘(’,‘)’,‘+’,‘-’,‘*’,‘/’,来实现四则运算,感觉不复杂. 然后开始coding.发现 ...
- [LeetCode] Binary Tree Postorder题解
Binary Tree Postorder Given a binary tree, return the postorder traversal of its nodes' values. For ...
- HDU 2578(二分查找)
686MS #include <iostream> #include <cstdlib> #include <cstdio> #include <algori ...
- 轻松学习java可重入锁(ReentrantLock)的实现原理(转 图解)
前言 相信学过java的人都知道 synchronized 这个关键词,也知道它用于控制多线程对并发资源的安全访问,兴许,你还用过Lock相关的功能,但你可能从来没有想过java中的锁底层的机制是怎么 ...
- sublime_text3 快速生成xhtml表头手动设置
1. 在github上手动下载emmet安装插件 https://github.com/sergeche/emmet-sublime#how-to-install 2.把下载的安装插件放到packag ...
- javascript之url转义escape()、encodeURI()和decodeURI(),ifram父子传参参数有中文时出现乱码
ifram父子传参参数有中文时出现乱码,可先在父级页面用encodeURI转义,在到子页面用进行decodeURI()解码 我们可以知道:escape()除了 ASCII 字母.数字和特定的符号外,对 ...
- java截取字符串
public class Temp { public static void main(String[] args) { String a="dsadgafa34"; System ...
- mysql中LOCATE和CASE WHEN...THEN...ELSE...END结合用法
之前项目中需要写一个sql,就是查出某个调研详情中,选A答案,B答案,C答案...F答案的人各有多少人,这个sql也是费了很大的力气才写出来,故记下来,方便以后使用. 其中tbl_research_i ...
- 配置文件出错 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): <!-- mybatis 配置- ...
- PRINCE2是什么意思?
PRINCE2是一种长期以来公认的项目管理方法,在英国公共部门广泛应用,在私营企业界也发展成为事实上的应用方法. PRINCE2开发于1989年,是一种结构性的项目管理方法,其所有者OGC(英国商务部 ...