4

spring cloud生态中Feign、Ribbon、loadbalancer的一些历史 - 三国梦回

 9 months ago
source link: https://www.cnblogs.com/grey-wolf/p/17902335.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

背景#

本意是想写个feign中loadbalancer组件和nacos相遇后,一个兼容相关的问题,后面发现Feign这套东西很深,想一篇文章写清楚很难,就先开一篇,讲历史。

Feign、OpenFeign、Spring Cloud OpenFeign#

Feign#

Feign是Java生态中的一个库,这个库的官方目标是:Feign makes writing Java http clients easier,大概就是让http接口调用更加容易。

查了下历史,最早是Netflix家的,坐标如下,16年发布了最后一个版本后停止维护:

<!-- https://mvnrepository.com/artifact/com.netflix.feign/feign-core -->
<dependency>
    <groupId>com.netflix.feign</groupId>
    <artifactId>feign-core</artifactId>
</dependency>

OpenFeign#

2016年,Netflix将其捐赠给社区,改名OpenFeign,目前还一直在维护:

<dependency>
    <groupId>io.github.openfeig</groupId>
    <artifactId>feign-core</artifactId>
</dependency>

Spring Cloud OpenFeign#

而Spring Cloud OpenFeign则是对Feign的集成,让Feign能更方便地在spring项目中使用。

项目主页:https://spring.io/projects/spring-cloud-openfeign#learn

Spring cloud这块有两个坐标,一个是用于集成改名前的Feign,最早的版本是2015年,目前,这个坐标早就标记为过期了,提示使用另一个: Spring Cloud Starter Feign (deprecated, please use spring-cloud-starter-openfeign)

https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-feign
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
    <version>1.0.0.RELEASE</version>
</dependency>

另一个则是集成改名后的OpenFeign,最早的版本是2017年11月20日,目前一直在维护,算是spring cloud中的核心组件:

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>1.4.0.RELEASE</version>
</dependency>

值得一提的是,不管是哪一个坐标,都是在第一个版本中,就已经依赖了ribbon这个组件,ribbon主要负责客户端负载均衡,因为根据服务名从服务注册中心会拿到很多实例,具体调用哪一个,就得靠ribbon这个组件来选择其中一个,比如随机、轮询等算法:

image-20231214210600179

spring-cloud-starter-openfeign:

image-20231214210651652

详情可参考文章:https://juejin.cn/post/7097124836496900127

Feign使用示例#

在feign中,比如要调用github的两个接口,只需要向下面这样定义好接口:

interface GitHub {
  @RequestLine("GET /repos/{owner}/{repo}/contributors")
  List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);

  @RequestLine("POST /repos/{owner}/{repo}/issues")
  void createIssue(Issue issue, @Param("owner") String owner, @Param("repo") String repo);
}

调用就像下面这样:

// 发起调用,调用第一个接口
GitHub github = Feign.builder().target(GitHub.class, "https://api.github.com");
List<Contributor> contributors = github.contributors("OpenFeign", "feign");

可以看出,它的思路就是简洁,就像调用普通的方法一样,不用考虑序列化、反序列化、流的打开和关闭、异常处理。

ribbon、spring cloud loadbalancer#

我应该是18/19年开始在项目里使用spring cloud,那时候的版本,还是spring cloud Netflix那一套,eureka + feign(ribbon) + hystrix断路器 + zuul网关那一套,ribbon是由OpenFeign默认引入的。

后来,Netflix宣布不再维护后,这一套中的组件,慢慢被替代。

前两年在鹅厂没搞spring cloud这一套,现在再搞这一套的时候,各个组件已经变天了。

在我们这,目前是,eureka变成了nacos,feign(ribbon)变成了feign(spring cloud loadbalancer),hystrix变成了sentinel,zuul网关变成了spring cloud gateway。

其中,feign是比较有意思的,之前的默认负载均衡组件是ribbon,但是ribbon因为也是Netflix家的,不再维护后,spring官方自己搞了个spring cloud loadbalancer。

spring cloud openfeign是从什么时候开始支持自家的loadbalancer呢?我翻了下历史,在2.1.5.RELEASE版本,都还只有ribbon(https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign/2.1.5.RELEASE)

下一个版本是2.2.0.RELEASE,已经开始支持loadbalancer了(https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign/2.2.0.RELEASE)。

当然,ribbon也还是支持的,只是多了个选择。

image-20231214214228342

spring cloud loadbalancer的最早版本也就是2.2.0.RELEASE,想必就是为了和openfeign的版本保持一致。

ribbon落幕#

我发现,OpenFeign目前主要有几个大版本。

2.2.x(从2.2.0.RELEASE到从2.2.10.RELEASE),这个版本都是有ribbon的,当然也有loadbalancer;

3.0.x,该版本是不带ribbon的,只有loadbalancer;

3.1.x,4.0.x,4.1.x,都是不带ribbon的,只有loadbalancer。

理清历史有什么用#

理清历史,可以让你对项目中的依赖和配置项更有掌控。

比如,ribbon和loadbalancer只需要一个就够了,没必要共存,那你会说,我肯定不会两个依赖同时引入。

没错,但是ribbon可能作为如下依赖的间接依赖被引入:

<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>

也就是说,nacos服务发现的2.2.x系列,默认引入ribbon。

image-20231214220634503

这样的话,你就可以排除掉多余的。

但你如果用的是nacos的2021.0.x系列,则它已经自己排除了ribbon系列,只支持loadbalancer了,就不需要手动排除了。

我就说我们有个项目很奇怪,为啥要手动排除ribbon:

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                    <groupId>org.springframework.cloud</groupId>
                </exclusion>
            </exclusions>
        </dependency>

我才发现,是项目的nacos服务发现坐标,从当时的2.2.x,升级到了:2021.0.5.0。我就说,排除个啥呀,本来都没这个依赖。

另外,之前还需要手动禁用ribbon:

spring:
  cloud:
    loadbalancer:
      ribbon:
        enabled: false

没理清楚这个历史前,我还不敢去掉这段配置,现在呢,直接删了就是。

这里,总结一下,就是说,如果项目里ribbon和loadbalancer共存,首先,这是没啥必要的,其次,共存情况下要使用loadbalancer,则还是需要上面这段禁用ribbon的配置的。

参考文章#

这篇是loadbalancer诞生的简介。

https://spring.io/blog/2020/03/25/spring-tips-spring-cloud-loadbalancer

https://baijiahao.baidu.com/s?id=1662947934543573780

博客分类导航贴:博客目录导航,让我们一起学起来吧(持续更新)

我是逐日, 前华为、前鹅厂大头兵,现在成都小公司躺平,可以关注我公号,想起来了就更新;或者右下角有个加号,咱们博客园见

20210108143914.png

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK