5.5、在Feign中使用HttpClient和OkhHttp

Feign 中、Client 是一个非常重要的组件,
Feign 最终发送 Request 请求以及接收 Response响应都是由 Client 组件完成的。
Client在Feign 源码中是一 个接口,
默认的情况下:
Client的实现类是 Client.Default
Client.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@ConditionalOnMissingBeanpublic 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
添加依赖:

配置文件中:
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.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、OkHttp
7、最后 Client 被封装到 LoadBalanceClient 类,这个类结合类 Ribbon 做到了负载均衡

转载于:https://www.cnblogs.com/Mrchengs/p/10646163.html

5、Spring Cloud-声明式调用 Feign(下)相关推荐

  1. 《深入理解 Spring Cloud 与微服务构建》第八章 声明式调用 Feign

    ·# <深入理解 Spring Cloud 与微服务构建>第八章 声明式调用 Feign 文章目录 一.Feign 简介 1.简介 2.工作原理 二.写一个 Feign 客户端 三.Fei ...

  2. 3.spring cloud + zookeeper注册中心 + Feign调用案例

    3.spring cloud + zookeeper注册中心 + Feign调用案例 3.1.pom.xml定义 <?xml version="1.0" encoding=& ...

  3. Spring Cloud微服务之Feign——声明式服务间调用

    目录 写在前面 服务间调用常见的方案 方案一:HttpClient 方案二:RestTemplate 方案三:Feign 框架版本问题及可能遇到的坑 搭建服务注册中心 搭建服务1--service-a ...

  4. 通过Feign实现Spring Cloud微服务调用

    我们在上一篇文章通过restTemplate实现Spring cloud微服务的调用中介绍了spring cloud微服务的一种调用方式,本文我们介绍另一种调用spring cloud微服务的方式-- ...

  5. Spring Cloud微服务之Feign服务调用(十一)

    Feign服务调用 一.Feign简介 基本概念 二.实现服务调用 1.编写删除源文件接口 2.在service模块添加pom依赖 3.在调用端(service_user)的启动类添加注解 4.新建一 ...

  6. (十四)Alian 的 Spring Cloud 订单服务调用自动生成的API

    目录 一.背景 二.maven依赖 三.主要编码 3.1.控制层 3.2.服务层 3.3.dto 3.4.主类 四.配置 4.1.bootstrap.properties 4.2.build.prop ...

  7. spring aop 之链式调用

    关关雎鸠,在河之洲.窈窕淑女,君子好逑. 概述 AOP(Aspect Orient Programming),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横 ...

  8. spring Cloud中,解决Feign/Ribbon整合Hystrix第一次请求失败的问题?

    Spring Cloud中,Feign和Ribbon在整合了Hystrix后,可能会出现首次调用失败的问题,要如何解决该问题呢? 造成该问题的原因 Hystrix默认的超时时间是1秒,如果超过这个时间 ...

  9. Spring cloud Eureka consumer 调用 provider ERROR:java.net.UnknownHostException: XXX-PAYMENT-SERVICE

    日常踩坑 不是在填坑,那就是在去挖坑的路上 控制台详情: 2020-08-01 10:48:02.709 ERROR 31608 --- [p-nio-80-exec-1] o.a.c.c.C.[.[ ...

  10. spring cloud 微服务调用--ribbon和feign调用

    这里介绍ribbon和feign调用两种通信服务调用方式,同时介绍如何引入第三方服务调用.案例包括了ribbon负载均衡和hystrix熔断--服务降级的处理,以及feign声明式服务调用.例子包括s ...

最新文章

  1. 用了三年 ThreadLocal 今天才弄明白其中的道理
  2. 【字节码插桩】Android 打包流程 | Android 中的字节码操作方式 | AOP 面向切面编程 | APT 编译时技术
  3. huggingface实操_Transformers 简介(上)
  4. Vue.js安装使用教程
  5. 11.m进制转十进制
  6. mapper同时添加数据只能添加一条_springcloud项目搭建第二节:eureka+数据库
  7. abaqus生成adams柔性体_Abaqus和STAR-CCM+流固耦合
  8. springboot mongo查询固定字段_SpringBoot中文参考指南(2.1.6)32、使用 NoSQL 技术
  9. dva开发一个cnode网站(2) 1
  10. 什么是远程桌面?花生壳+Windows远程桌面控制教程
  11. 遥感影像转换成MapGIS识别的msi格式
  12. 用友凭证打印故障解决
  13. win linux批处理删除指定N天前文件夹的文件
  14. 嵌入式、单片机之间的区别
  15. 立体栅格地图_基于八叉树表示的三维栅格地图路径规划系统及方法与流程
  16. python之if-else_Python中的if-else
  17. 【Typescript专题】之类型进阶
  18. MAC自带词典添加词典文件
  19. 玩吃鸡台式计算机配置,玩转绝地求生:大逃杀!i5-7400配GTX1060玩游戏的台式机配置推荐...
  20. “互联网汽车”又添新成员,上汽斯柯达接入斑马智行互联系统

热门文章

  1. nginx 安装失败 没有/etc/nginx目录
  2. Ubuntu 12.04中设置安装Google拼音输入法
  3. GDB调试精粹及使用实例来源-转
  4. gdb 调试 入手 实例讲解-转
  5. mysql for rhel7_MySQL5.7.18 for Linux7.2(二进制安装)
  6. VC6.0调试知识大全
  7. 【剑指offer】5.二叉树的镜像和打印
  8. 挨踢部落坐诊第六期:机器学习如何判断突发情况?
  9. 【转载】cocos2d-x类型转换(CCstring int string char UTF-8互转)以及字符串详解
  10. iOS内存分配五大区: