OpenFeign第一个可扩展组件通信Client详解

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: 这篇文章详细分析了OpenFeign框架中的第一个可扩展组件——通信Client,包括其默认实现`feign.Client.Default`,以及如何使用`LoadBalancerFeignClient`集成负载均衡能力,并探讨了如何替换默认的`HttpURLConnection`通信组件为`OkHttpClient`或`ApacheHttpClient`。

前言

之前的文章 OpenFeign十大可扩展组件你知道哪些?有说过Openfeign有10大可扩展组件:

image.png

image.png 我们今天详细分析第一个 feign.Client,还有Spring默认提供的负载均衡能力的通信客户端org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient, client组件应属于feign框架中最核心的组件,因为它承担着rpc框架最关键的能力-发起远程通信

feign.Client默认实现

在feign的原生包里面,有一个默认的实现feign.Client.Default

image.png

默认使用的是Java原生的HttpURLConnection来发起通信,

image.png

这里是官方对HttpURLConnection的介绍,感兴趣的可以查看

Java官方提供的基于Socket的基础通信组件,api的使用比较麻烦,比如需要发起一个http请求,我们需要这样写:

//根据请求地址构造URL对象
URL url = new URL("http://www.baidu.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
   
    InputStream in = new BufferedInputStream(urlConnection.getInputStream());
    //需要自行操作流
    List<String> result = IOUtils.readLines(in);
    for (String r : result) {
   
        System.out.println(r);
    }
} finally {
   
    urlConnection.disconnect();
}

image.png

HttpURLConnection没有封装好的http网络库使用便捷。比okhttp,apache,httpcompent,我们的应用程序一般会使用到封装好的库进行通信。 下面是okhttp的写法:

@SneakyThrows
public static void main(String[] args) {
   
    OkHttpClient okHttpClient = new OkHttpClient();
    Request request = new Request.Builder().url("http://www.baidu.com").build();
    Response reponse = okHttpClient.newCall(request).execute();
    System.out.println(reponse.body().string());
}

image.png

相比okhttp,HttpURLConnection使用上更费劲,而okhttp提供了极好的便捷性和扩展性,从下方构造函数看,okhttp组件提供了很多扩展点,比如拦截器,缓存,代理等,同时如果想做负载均衡的话,是不支持的。

image.png

LoadBalancerFeignClient登场

于是LoadBalancerFeignClient出现了,LoadBalancerFeignClient是集成了负载均衡能力的客户端,同时它持有了抽象的通信client组件的引用。

image.png feign本身不提供负载均衡的能力,默认会使用ribbon负责负载均衡处理。

LoadBalancerFeignClient它是如何生效的呢?也就是说怎么替换feign里默认的通信feign.Client
DefaultFeignLoadBalancedConfiguration里面利用了自动装配机制进行覆盖

package org.springframework.cloud.openfeign.ribbon;

/**
 * @author Spencer Gibb
 */
@Configuration
class DefaultFeignLoadBalancedConfiguration {
   

   @Bean
   @ConditionalOnMissingBean
   public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
         SpringClientFactory clientFactory) {
   
      return new LoadBalancerFeignClient(new Client.Default(null, null), cachingFactory,
            clientFactory);
   }

}

openfeign如何替换默认的HttpUrlConnection

这种情况还是使用的httpUrlConnection通信组件,如果想使用okhttp或者apache-http-client怎么办呢?

Spring团队也早想到了,分别给我们提供了一个配置类

package org.springframework.cloud.openfeign.ribbon;

/**
 * @author Spencer Gibb
 */
@Configuration
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnProperty("feign.okhttp.enabled")
class OkHttpFeignLoadBalancedConfiguration {
   

   @Bean
   @ConditionalOnMissingBean(Client.class)
   public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
         SpringClientFactory clientFactory, okhttp3.OkHttpClient okHttpClient) {
   
      OkHttpClient delegate = new OkHttpClient(okHttpClient);
      return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
   }
}

你们项目中是否有使用过上方这个配置feign.okhttp.enabled呢?

下面是使用ApacheHttpClient替换默认通信组件

package org.springframework.cloud.openfeign.ribbon;

/**
 * @author Spencer Gibb
 */
@Configuration
@ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
class HttpClientFeignLoadBalancedConfiguration {
   

   @Bean
   @ConditionalOnMissingBean(Client.class)
   public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
         SpringClientFactory clientFactory, HttpClient httpClient) {
   
      ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
      return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
   }
}

写到这里又想抱Spring团队大佬的大腿了,每个组件都能写的这么灵活。

image.png

总结篇

Client组件默认使用HttpURLConnection实现通信,而LoadBalancerFeignClient是将负责均衡和通信能力组合的。由于负载均衡能力是ribbon提供的,本文只分析到此,下文将分析ribbon是如何给openFeign增加负载均衡能力的。

image.png

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
4月前
|
Java 开发工具 Spring
【Azure 事件中心】azure-spring-cloud-stream-binder-eventhubs客户端组件问题, 实践消息非顺序可达
【Azure 事件中心】azure-spring-cloud-stream-binder-eventhubs客户端组件问题, 实践消息非顺序可达
|
5月前
|
消息中间件 API 数据库
在微服务架构中,每个服务通常都是一个独立运行、独立部署、独立扩展的组件,它们之间通过轻量级的通信机制(如HTTP/RESTful API、gRPC等)进行通信。
在微服务架构中,每个服务通常都是一个独立运行、独立部署、独立扩展的组件,它们之间通过轻量级的通信机制(如HTTP/RESTful API、gRPC等)进行通信。
|
6月前
|
存储 C++
gRPC 四模式之 双向流RPC模式
gRPC 四模式之 双向流RPC模式
239 0
|
自然语言处理 负载均衡 算法
Nacos架构与原理 - 通信通道
Nacos架构与原理 - 通信通道
128 1
|
Dubbo Java 应用服务中间件
如何在Spring Boot项目中集成Dubbo并启用gRPC协议,来实现高效的分布式服务通信?
如何在Spring Boot项目中集成Dubbo并启用gRPC协议,来实现高效的分布式服务通信?
242 0
如何在Spring Boot项目中集成Dubbo并启用gRPC协议,来实现高效的分布式服务通信?
|
前端开发 Cloud Native Java
使用Spring WebSocket实现实时通信功能
使用Spring WebSocket实现实时通信功能
110 0
|
传感器 Cloud Native 物联网
gRpc的四种通信方式详细介绍
gRpc的四种通信方式详细介绍
233 0
|
应用服务中间件 nginx 数据中心
理解Registrator、Nginx、Consul架构与SpringCloud Feign、grpc、rest通信之间的不同点
在互联网应用领域,服务的动态性需求十分常见,这就对服务的自动发现和可动态扩展提出了很高的要求。
160 0
|
消息中间件 XML JSON
一文就读懂RPC远程调用核心原理
rpc的全称是Remote Procedure Call,即远程过程调用,是分布式系统的常用通信方法。 Remote,简单来说的话就是两个不同的服务之间,两个服务肯定是两个不同的进程。因此,我们就从跨进程进行访问的角度去理解就行了。 Procedure,意思是一串可执行的代码,我们写Java的方法,就是一段课程行的代码。 Call,即调用,调用的就是跨了进程的方法。
381 0
一文就读懂RPC远程调用核心原理
|
消息中间件 存储 设计模式
Seata 高性能 RPC 通信的实现- 巧用 reactor 模式
reactor 模式是一种事件驱动的应用层 I/O 处理模式,基于分而治之和事件驱动的思想,致力于构建一个高性能的可伸缩的 I/O 处理模式
184 0