首页 技术 正文
技术 2022年11月19日
0 收藏 790 点赞 2,646 浏览 4672 个字

5.5、在Feign中使用HttpClient和OkhHttp

Feign 中、Client 是一个非常重要的组件,Feign 最终发送 Request 请求以及接收 Response响应都是由 Client 组件完成的。 Client在Feign 源码中是一 个接口,默认的情况下:Client的实现类是 Client.DefaultClient.Default 是由 HttpURLConnnection 来实现网络请求的。Client 支持 HttpClient、OkhHttp 来进行网络请求。 FeignRibbonClient 的自动配置类 FeignRibbonClientAutoConfiguration

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;
}
}

1、若要使用HttpClient在pom添加依赖:

<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>

配置文件中:

feign.httpclient.enabled=true

从新启动即可(具体看源码进行分析)

2、同理若要使用OkHttp添加依赖:

5、Spring Cloud-声明式调用 Feign(下)

配置文件中:feign.okhttp.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执行请求的方法

executeWithLoadBalancer()方法:通过负载均衡的方式来执行网络请求代码如下:

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);
}
}
}

submit()方法:进入方法内部:可以看出它是LoadBalancerCommand类的方法

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、Spring Cloud-声明式调用 Feign(下)

5.7、总结

1、首先通过@EnableFeignClients 注解开启 FeignClient 的功能。只有这个注解存在,才会在程序启动时开启对@FeignClient 注解的包扫描2、根据 Feign的规则实现接口,并在接口上面加上@FeignClient注解3、程序启动后,会进行包扫描,扫描所有的@ FeignClient 注解 ,并将这些信息注入 IoC 容器中。 4、当接口的方法被调用时 通过 JDK 的代理来生成 体的 RequestTemplate模板对象5、根据 RequestTemplate 再生成 Http 请求的 Request 对象6、Request 对象交给 Client 去处理 其中 Client 的网络请求框架可以是 HttpURLConnect on、HttpClient、OkHttp7、最后 Client 被封装到 LoadBalanceClient 类,这个类结合类 Ribbon 做到了负载均衡

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,489
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,904
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,737
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,490
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,128
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,290