北京时间2020-12-22深夜,Spring Cloud 2020.0.0
版本正式发布。2020.0.0是第一个使用新版本方案的Spring Cloud发行版本。
关于版本号这里啰嗦几句:在这之前,Spring Cloud的Release Train名称采用的是伦敦地铁站命名方式,如:Hoxton、Greenwich等。
说明:2020.0.0版本又名
Ilford
(地铁站名),因为此项目3月后才按照新规更名,估计是为了团队内沟通方便吧,你也可以理解为它仅是一个内部代号而已,方便沟通
虽按照字母表顺序排列,但仍存在两个致命问题:
对非英语母语国家(比如天朝)非常不友好,无法快速理清版本号关系
A-Z,倘若版本号到Z了呢?如何继续发展?你品,你细品
Spring团队意识到了这的确是个问题,因此在今年3月份作出了改变。详情参考我前面写的一篇文章(强烈建议每个进来的你都了解下这次规则变更):Spring改变版本号命名规则:此举对非英语国家很友好
说明:版本号规则变更适用于所有Spring技术栈,包含Spring Framework、Spring Boot、Spring Cloud、Spring Data...
文归正传。Spring Cloud早在年初就启动了该版本的研发工作,并在今年4月份就已经发布了其2020.0.0-M1版本(第一个里程碑版本),直到离2020年结束不到10天了才“憋出”大招,正式RELEASE。
Spring Cloud作为构建在Spring Boot之上的云计算框架,我觉得本次难产的原因主要有二:
- Spring Boot 2.4.0版本2020-11-12才正式RELEASE(Spirng Framework 5.3.0版本2020-10-27才RELEASE)
1. Spring Framework 5.3.0正式发布,在云原生路上继续发力
2. Spring Boot 2.4.0正式发布,全新的配置文件加载机制(不向下兼容)
- 改动确实太大,研发、测试、文档编写工作量都是巨大的
从Spring Framework、Spring Boot、Spring Cloud三者的发版线路图再一次验证了我的那句话:你对Spring Cloud多了解源自于你对Spring Boot有多了解,你对Spring Boot多了解源自于你对Spring Framework有多了解。这就是为何我文章花大量笔墨在Spring Framework上而非Spring Boot上的根本原因,底层通透了,上层运用自如。
版本约定
Spring Framework:5.3.2
Spring Boot:2.4.1
Spring Cloud:2020.0.0
- 以上版本为SC“携带”的版本
✍正文
有个有趣的现象,截止稿前(2020-12-23 22:00:00)官网还并未同步标注好当前最新版本为2020.0.0版(如图):
其实早在24h之前官方博客就做出了发版宣告:
并且Maven中央仓库也已存在最新Jar包(证明你正常引包、使用是没问题的了):
其实,文档层面不止官网这一处没有sync最新版本,我就不一一例举,毕竟不太重要。针对此现象我yy一下,是不是Spring Cloud团队缺人人手不够用呢?请问社招吗?O(∩_∩)O哈哈~
Spring Cloud版本管理
版本管理对于软件开发来说太重要,在Spring Boot出现之前依赖关系、版本管理让人着实头大(即使有Spring BOM存在),特别是当出现版本不适配时很容易就偷走你一下午甚至一整天的时间。
Spring Cloud作为上层应用框架,底层版本匹配了才能正常work,其中最主要就是和Spring Boot的版本号要对齐。
与Spring Boot版本对应关系
Spring Boot的出现和流行大大缓解了上述些情况,但使用起Spring Cloud时它和Spring Boot的版本对应关系依旧是需要特别关注的。为此我帮你总结出了这个表格:
Release Train | 发布时间 | Spring Boot版本 | SC Commons版本
-------- | ----- | ----- | -----
2020.0.x | 2020-12 | 2.4.x | 3.0.0
Hoxton | 2019-07 | 2.2.x, 2.3.x (从SR5起) | 2.2.x
Greenwich | 2018-11 | 2.1.x | 2.1.x
Finchley | 2017-10 | 2.0.x | 2.0.x
Edgware | 2017-08 | 1.5.x | 1.3.x
Dalston | 2017-05 | 1.5.x | 1.2.x
Brixton | 2016-09 | 1.3.x | 1.1.x
Angel | 2016-05 | 1.2.x | 1.0.x
说明:对于Spring Cloud内部组件、Spring Boot、Spirng Framework、Security等这个庞大体系的版本对照关系,文章已整理好,下篇发出,请记得搜藏哦
特别提醒:spring-cloud-starter-loadbalancer
是伴随着Spring Cloud Commons 2.2.0版本才开始商用的(Hoxton版本),这个版本节点请稍微关注下,因为它替代了Ribbon。
当前支持的版本
Spring Cloud遵循Pivotal OSS support policy 协议对主要版本提供3年的支持。此外,在Spring Cloud的主要或次要版本发布后,若存在严重的bug和安全问题,就会再维护一段时间(6-12个月不等)。
特别注意:这里指的主要版本才是3年,主要版本可不常有的哦
现在2020.0.0版本已发布,又到了淘汰的时候。现在Spring Cloud官方还会支持的版本有:
- 2020.0版本:(支持Spring Boot 2.4.x)它是主要版本,按计划会支持到2023年12月份
- 它是自Finchley后的又一主要版本
Hoxton版本:(支持Spring Boot 2.2.x和2.3.x)作为Finchley发行系列的一个次要版本,它的常规维护将持续到2021年6月底。从2020-07开始进入到特殊维护期(不加新功能,只改紧急bug),2021-12月底就只会发布重大错误/安全补丁了
Greenwich版本:(支持Spring Boot 2.1.x)2020-01就停止维护了,2020-12-31号也将终结它的特殊维护期
Finchley版本:(支持Spring Boot 2.0.x)它是一个主要版本的开始,2018年发布
更老版本:嗯,忘了吧
Spring官方建议:尽量使用最新版本。不过建议归建议,作为只使用晚期大众技术的我们,坐在第二排甚至第三排看戏才有安全感。但历史的巨浪总归会把前排淘汰,因此早点做足准备总是好的,不至于时至被推至前排时只能裸泳。
Spring Cloud 2020.0作为一个主要版本,带来了众多显著的变化,其中进行了一些阻断式更新(不向下兼容)是本文最大看点,来吧上菜。
阻断式升级(不向下兼容)
差不多在去年(2019年)的这个时候,Spring Cloud在其Roadmap(之前文章有介绍过)里就宣布将要终结的一些库/版本,其中最重要的就是指Spring Cloud Netflix项目进入维护模式,然后计划在2020年完全移除。
Spring Cloud做出这样的决定其实也是“被迫的”。我们知道Spring Cloud一直以来把Netflix OSS
套件作为其官方默认的一站式解决方案,那时的Netflix OSS套件恨不得可以跟Spring Cloud划等号。奈何呀,Netflix公司在2018年前后宣布其核心组件Hystrix、Ribbon、Zuul、Archaius等均进入维护状态。
虽然有Zuul 2.x,Archaius 2.x,但它们均不能向下兼容,无法平滑升级,因此几乎等于无法使用
从2018年至今处于维护状态的模块有(包括其对应的starter,此处并未列出):
spring-cloud-netflix-archaius
spring-cloud-netflix-hystrix-contract
spring-cloud-netflix-hystrix-dashboard
spring-cloud-netflix-hystrix-stream
spring-cloud-netflix-hystrix
spring-cloud-netflix-ribbon
spring-cloud-netflix-turbine-stream
spring-cloud-netflix-turbine
spring-cloud-netflix-zuul
1、再见了,Netflix
时至今日,Spring Cloud 2020.0正式发布,在这个主要版本里,按既定计划终于对spring-cloud-netflix
动刀了。我帮你画了幅spring-cloud-netflix-dependencies
的xml文件前后版本主要差异的对比图,一目了然:
spring-cloud-netflix-dependencies
没有消失哦,它依旧存在,版本号跟随大部队升级为3.0.x版本旧版本的
spring-cloud-netflix-dependencies
管理着Netflix所有组件,包括Hystrix、Ribbon、Zuul、Eureka等。而自2020.0版本起,它有且只管理Eureka(包括Server和Client)
解释说明:Feign虽然最初属Netflix公司,但从9.x版本开始就移交给OpenFeign组织管理了,因此不再划入Netflix管辖范畴
简单一句话概括:Spring Cloud 2020.0.0版本彻底删除掉了Netflix除Eureka外的所有组件。至此,我们怀着感恩的心可以对Netflix OSS套件道一声谢谢,并可以对它说再见了。
说明:Netflix的Eureka项目仍旧是活跃状态,这个注册中心设计上还是蛮优秀的,综合表现尚可,市场上竞争力依旧可圈可点,因此Spring Cloud暂还未放弃它
<pre lang="xml" data-origin="pm_code_preview" style="margin: 0px; padding: 0px; list-style: none; font-family: Courier, "Courier New", monospace; display: block;">
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</pre>
Netflix组件替代方案
Spring Cloud既然把Netflix OSS套件大刀阔斧的砍掉了,那总归得有替代方案吧。那是必然的,Spring Cloud团队给我们推荐了用于替代的产品:
Netflix | 推荐替代品 | 说明
-------- | ----- | -----
Hystrix | Resilience4j | Hystrix自己也推荐你使用它代替自己
Hystrix Dashboard / Turbine | Micrometer + Monitoring System | 说白了,监控这件事交给更专业的组件去做
Ribbon | Spring Cloud Loadbalancer | 忍不住了,Spring终究亲自出手
Zuul 1 | Spring Cloud Gateway | 忍不住了,Spring终究亲自出手
Archaius 1 | Spring Boot外部化配置 + Spring Cloud配置 | 比Netflix实现的更好、更强大
Spring Cloud LoadBalancer是什么?
以上替代品中,你可能最陌生、最好奇的是Spring Cloud Loadbalancer
,它一度只是Spring Cloud 孵化器里的一个小项目,并且一度搁浅。后再经过重启,发展,现行使其伟大使命,正式用于完全替换 Ribbon,成为Spring Cloud负载均衡器唯一实现。
值得注意的是:Spring Cloud LoadBalancer首次引入是在Spring Cloud Commons 2.2.0时,也就是Hoxton发布时就引入了,只不过那会还只是备胎/备选,默认依旧是Ribbon挑大梁。下截图是在Hoxton版本的情况:
如图,负载均衡抽象LoadBalancerClient
接口有两个实现,而到了Spring Cloud 2020.0版本后,BlockingLoadBalancerClient
就是唯一实现了。
关于spring-cloud-loadbalancer负载均衡器的使用,官方有个极其建议教程:https://spring.io/guides/gs/spring-cloud-loadbalancer。有兴趣可自己玩玩,若没兴趣,那就关注我后面文章分析吧,我会专程介绍它的
Spring Cloud Alibaba是否可作为替代方案?
嗯,也可以。
不过它目前来说并不是Spring Cloud官方的推荐的默认方案。期待国人一起努力,能早日送Spring Cloud Alibaba上去,让歪果仁用上咱天朝的框架,提issue必须用中文O(∩_∩)O哈哈~。
显示导入Netflix包还能否正常work?
既想升级到最新版本的Spring Cloud,又想保持向下兼容使用Netflix的技术。虽说spring-cloud-netflix-dependencies里不再包含netflix的核心组件,那我手动导包并指定版本号行不行?能否正常work呢?
答:我拍脑袋就给你个答案,不行。既然我没论证过,但这么使用太畸形了,此方案应被枪毙在萌芽中,不应该有。
另外,从此事也告诉我们:使用Spring Cloud时尽量面向它的抽象编程,这样即使Spirng Cloud换底层组件(如换熔断器、负载均衡器)等等,理论上对我们业务是无影响或者影响很小的,这都得益于它的Spring Cloud Commons抽象,那里是精华。
2、Bootstrap上下文默认不再启动
知晓原理的同学知道,Spring Cloud容器是靠Bootstrap Context
引导上下文来启动的,对应的类是BootstrapApplicationListener
。
这在2020.0版本发生了改变,新版本的Spring Cloud不再依赖于此上下文而启动。因此默认情况下,将不再启动Bootstrap上下文。代码层面的改变发生在这里:
<pre lang="java" data-origin="pm_code_preview" style="margin: 0px; padding: 0px; list-style: none; font-family: Courier, "Courier New", monospace; display: block;">
BootstrapApplicationListener:
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
// 在方法开头加了这麽个判断
if (!bootstrapEnabled(environment) && !useLegacyProcessing(environment)) {
return;
}
...
}
PropertyUtils:
// BOOTSTRAP_ENABLED_PROPERTY = spring.cloud.bootstrap.enabled
public static boolean bootstrapEnabled(Environment environment) {
return environment.getProperty(BOOTSTRAP_ENABLED_PROPERTY, Boolean.class, false) || MARKER_CLASS_EXISTS;
}
// USE_LEGACY_PROCESSING_PROPERTY = spring.config.use-legacy-processing
public static boolean useLegacyProcessing(Environment environment) {
return environment.getProperty(USE_LEGACY_PROCESSING_PROPERTY, Boolean.class, false);
}
</pre>
开启方式
若你需要开启Bootstrap上下文,有两种办法可以实现:
设置值
spring.cloud.bootstrap.enabled=true
或者spring.config.use-legacy-processing=true
即可。注意:这些个属性值必须确保其能放进环境里才能生效。比如靠谱的方式是:系统属性、环境变量、命令行等引入一个Jar:
org.springframework.cloud:spring-cloud-starter-bootstrap
,然后什么都不用做了
1. 说明:这个jar里面有且仅有一个Marker
类,作用你懂的,此处不做过多解释
说明:手动开启Bootstrap上下文,证明你fallback到老的方式去加载SC,那么一切请按照老方式做即可
3、全新的配置方式
得益于Spring Boot 2.4.x支持全新的配置文件书写方式,自此可以使用spring.config.import
俩导入其它组建的配置。如:
spring.config.import=configserver:xxx
spring.config.import=zookeeper:
...
这么做更具模块化,更符合云原生环境的要求。
4、其它
之前若要禁用Spring Cloud Config Client端的健康指示用的是
health.config.enabled=false
,现改为management.health.config.enabled=false
。保持了和Spring Boot控制端点风格一致带有无效字符(破折号)的端点id已经改为符合标准的了,自此启动时再也没有讨厌的警告了,拯救洁癖者。
bus-env -> busenv
bus-refresh -> busrefresh
service-registry -> serviceregistry
<pre lang="java" data-origin="pm_code_preview" style="margin: 0px; padding: 0px; list-style: none; font-family: Courier, "Courier New", monospace; display: block;">
// old
@Endpoint(id = "service-registry")
public class ServiceRegistryEndpoint { ... }
// new
@Endpoint(id = "serviceregistry")
public class ServiceRegistryEndpoint { ... }
</pre>
常规式升级
常规升级这块关注点就没那么多了,主要对其组件如Spring Cloud Commons、Spring Cloud Kubernetes、Spring Cloud Openfeign...
等做些常规升级,乏善可陈。
值得关注的一点:Spirng Cloud所有的Module版本号均升级到了3.0.0
(大版本号的升级),除Spring Cloud Circuitbreaker/Spring Cloud Kubernetes(2.0.0)和Spring Cloud Task(2.3.0)之外。
仍旧存在的问题
虽然2020.0已经RELEASE了,但是仍存在着未解决的问题,例举几个此版本现存的问题:
- 若使用
spring.config.import=configserver:
来配置配置中心,此版本漏掉了支持retry参数
- 解决方案:若你要使用的话,你只得fallback到传统方式喽(写在bootstrap.yaml里)
-
spring-cloud-config-dependencies
里出现了一个非release版本的jar(具体看下截图)
- 解决方案:手动指定该jar的版本号
说明:M1属于里程碑版本,还属于较为早起阶段,可能存在bug,建议你使用时手动指定版本号替换掉这个jar
看来即使强如Spring团队,也会出现各种各样的纰漏呀。这么一想的话,我又敢放心大胆的回去写bug去喽。
✍总结
Spring Cloud 2020.0.0是Spring Cloud的主要版本,是非常重要的存在,升级、改变也是巨大的。特别体现在Netflix模块的全部移除、Spring Cloud启动方式变了等等。伴随着Spring Boot 2.4.x以及Spirng Cloud 2020.0的发布,并且弃用Netflix OSS套件后,必将走入一个新的深度编程体验,满怀惊喜,很是期待。
说明:因为此版本完全摈弃掉了Netflix的一套东西,为了跟上时代,我会使用一段时间后,尽快写出最新版本的系列教程,助你少踩坑
文末有提到2020.0版本虽已发布,但仍旧存在些问题。不过话说回来,那些都属于很小的问题,可能在下个小版本里就得到修复。但尴尬的是,距离2020年结束只有不到10天了,倘若进入到了2021年,按照版本号命名新规,彼时发出的版本将不能再叫2020.x.x而只能是2021.x.x,显然这就属于大版本号的迭代了,需要谨慎啊