领先一步
VMware 提供培训和认证,助您加速提升。
了解更多各位 Spring 粉丝们,大家好!
你们知道我干了什么吗?我搞砸了,各位。我不小心在今年十二月的最后一周,也就是全年的最后一个月,发布了《本周 Spring》!我本不该那样做的。我**不**该那样做。通常,我会把一年中最后一期的《本周 Spring》变成恰如其名的《本年 Spring》,以此来庆祝定义了这一年的重要主题(至少从我的角度来看是这样)。然后我会在其中包含通常的《本周 Spring》摘要。我忘了做前一部分,所以我把这篇文章单独发布。嘿,这可是**传统**。
啊,2020。真是没完没了的一年。这是《虎王》流行的一年。如果你在 2019 年告诉我,到 2020 年我会宅在沙发上看 Netflix 上关于驯虎师的冒险故事,害怕我的送货杂货,并且急切地想在十个月以来第一次登上飞机,我一定会笑得从椅子上摔下来!
今年,2020 年,开局非常精彩。在 VMware 收购 Pivotal 之后,2020 年是 Spring 团队回归的第一个年头(差不多)。你们可能知道,在 2013 年我们分拆成立 Pivotal 之前,Spring 团队曾在 VMware 工作了几年。现在我们回来了。你**可能觉得**这会带来混乱,但事实并非如此。Pivotal 和 VMware 都致力于帮助客户将产品投入生产。我们迅速投入工作,并持续推出重要更新和频繁交付。
这种兴奋感在今年史诗般的 SpringOne 2020(线上)活动中最为明显,该活动吸引了来自各行各业、各种信仰、各个国家和各个大洲的约 40,000 人。那真是甜蜜的源泉,我永远不会忘记。
Spring 团队一直以来地理位置分布广泛,这也有所帮助。例如,我从 2010 年起就正式成为了居家办公的员工。虽然今年因为**很多**原因而额外压力巨大,而且就是额外**不寻常**,但对我们很多人来说,摸索居家办公的日常并非其中之一。
当我写下这些文字时,时间是 2020 年 12 月 30 日,距离疫情消息开始零星传到西方已有一年。我不想成为**那样**的人,但今年我确实有亲人因 COVID-19 离世。我也有朋友今年使用过呼吸机。我也认识失去了亲友的人。对全世界许多人来说,这真是一场彻头彻尾的恐怖秀。然而,不知何故,我有幸能够继续撰写关于软件的博客。这都要归功于你们,亲爱的社区。虽然我一直非常感谢你们,但今年尤其如此。为你们工作是我的荣幸。
疫情像野火一样蔓延(有些东西真的**不该**开源!),它也淹没了许多其他有时更积极的消息。本着这种精神,我想回顾一下 2020 年的一些亮点——一些重要的主题。
您可能听说过 VMware Tanzu。您可能听说过 Spring 团队是 Tanzu 的一部分。您是否还知道 Kubernetes 的三位创始人中有两位也是 Tanzu 的一部分?您是否知道 VMware 是 Kubernetes 的第三大贡献者?我们对 Kubernetes 太痴迷了!
Tanzu Kubernetes Grid 是我们超赞的 Kubernetes 发行版,可用于本地或公共基础设施。Harbor 是企业级容器注册表。Tanzu Mission Control 提供跨云的多集群 Kubernetes 管理。VMware 还是 Carvell 的重要贡献者,Carvell 提供了一套可靠、专用、可组合的工具,可帮助您构建、配置和部署应用程序到 Kubernetes。我们有 Tanzu Build Service,它可以在企业规模下自动化容器的创建、管理和治理。我相信我肯定还漏掉了无数其他东西。
我们甚至对我们的平台即服务产品 Cloud Foundry 进行了改造,使其可以在 Kubernetes 之上运行。它提供同样流畅以开发者为中心的工作流程体验,并结合了全功能的 Kubernetes 容器编排。
近年来,我们做了**大量**工作,使 Java 和 Spring 在 Kubernetes 等容器化云基础设施中更具相关性。
今年,Spring Boot 通过 CNCF Paketo buildpacks 项目引入了对 buildpacks 的内置支持。您的 Spring Boot 项目使用的是 2.3 或更高版本吗?试试这个:mvn spring-boot:build-image
(也有相应的 Gradle 命令),大约一分钟后您就能得到一个容器化的应用程序。然后您就可以将这个容器化应用程序 docker tag
并 docker push
到您选择的 Kubernetes 集群中。或者,实际上,推送到任何支持 OCI/Docker 镜像的地方。
Spring Boot 本身现在可以从**配置树(config trees)**中获取配置。配置树是您在 Kubernetes 中将 Kubernetes ConfigMap
作为卷挂载时获得的配置目录。这是另一种配置源,就像 classpath 配置(application.properties
、application.yaml
等)、环境变量、文件(file://${user.home}/config/my-config.properties
)等等一样。
Spring Boot 的 Actuator 模块可以暴露端点作为 Kubernetes 的存活探针(liveness probe)和就绪探针(readiness probe)。就绪探针告诉 Kubernetes 一个刚刚启动的服务是否已准备好投入使用。存活探针告诉 Kubernetes 服务是否仍然存活。如果服务由于某种原因出现问题,它将被从轮换中移除。
那么应用程序面临的问题是:Kubernetes 应该立即销毁应用程序,还是应该等待配置的时间间隔以允许正在进行的事务完成?这种行为在 Kubernetes 中是可配置的。Spring Boot 通过一项我们称之为优雅停机(graceful shutdowns)的新功能,支持耗尽所有正在进行的事务并拒绝任何新的请求。
Spring Boot 及其生态系统,包括 Spring Cloud for Kubernetes,是构建面向云原生 Kubernetes 环境软件的最佳方式,而且情况每天都在改善。不过,我们才刚刚开始,所以请保持关注!
响应式编程是一种编程范式,它提供了三个好处:资源效率、数据 API 的一致性和可组合性以及鲁棒性。它通过轻松编写能很好地释放闲置线程以便重用的代码,从而提高了资源效率。它提供了一致性,因为它给了我们一个抽象,一种思考不同数据流的方式。数据是以 Java 8 Stream<T>
形式传入?Collection<T>
?CompletableFuture<T>
?单个值还是数组?没问题。响应式编程提供了一种方式,让我们能够以一致的方式,用这些 API 来描述数据流管道。
学习响应式类型确实有一些挑战。然而,考虑到这些类型在整个生态系统中所有可能的应用场景,我认为您会发现您可以**忘掉**许多其他的抽象和 API。Spring 生态系统自 2011 年起就(适度地)支持了响应式编程,但真正的飞跃是在 2017 年,我们在 Spring Framework 5 中引入了响应式编程支持。从那时起,响应式编程已经渗透到 Spring 生态系统的方方面面。我不记得上一次我在响应式世界中寻求某个功能,结果却被告知它仍在开发中的情况了。至少在 2020 年,这绝对没有发生!
我想要的一切现在都已经在这里,并且通常都是可用的。事务、SQL 数据访问、消息和集成、响应式客户端负载均衡、重试、限流、API 网关、NoSQL 数据访问、HTTP、WebSocket、RPC、度量、分布式追踪、可观测性:**所有**这些(以及我能想到的其他所有东西)现在都**开箱即用**。未来是非阻塞的,而 Spring,以它今天的设计,将与您一同走在最前沿。我写了一本关于这些内容的书并已出版,所以请相信我,这些东西非常棒。响应式编程是一种强大的方式,可以使我们的服务在云中表现得更好(并且更具伸缩性!)。
原生镜像将长久存在,它们**太棒了**。这一切看起来如此简单。如果我们利用 Java 传奇的即时编译器(HotSpot),提前、主动地编译整个应用程序呢?这听起来简单得荒谬。这个过程——将源代码转换成本地代码——在许多其他语言中就叫做**编译**。而编译成字节码引入的间接性迫使我们为这种新的直接路径采用了一个新术语:**提前编译(ahead-of-time-compilation, AOT)**。哦。啊。
简单。但事实证明并非如此。因为一旦编译成原生镜像,应用程序的运行时环境与在 JVM 中运行时不同。编译成原生镜像后,运行时将无法执行我们在 JVM 中习惯的那些更动态的“派对技巧”。想将类加载到类加载器中?使用 CGlib 代理?在没有**先验**运行时感知的情况下对类进行反射?从类加载器加载资源(例如,banner.txt
文件)?在 GraalVM AOT 编译这个古怪但精彩的世界里,所有这些都行不通了。
Spring GraalVM 项目可以在这方面帮助您。它支持识别 Spring 应用程序可能需要执行这些操作的所有位置,并为任何需要配置的操作提供注册帮助。该项目正在突飞猛进地发展,目标是到 Spring Boot 3 和 Spring Framework 6 时,所有这些都将内置并开箱即用。
作为对所有这些附带复杂性的回报,GraalVM 显著提高了启动速度,并显著减少了内存占用。这使得 GraalVM 成为了(好得多的)bin-packer,尤其是在容器化云环境中,资源消耗是成本所在。我也迫不及待地想看看 Project Leydon 的未来会怎样!
RSocket 是一种二进制协议,它使得微服务之间的消息交换变得轻而易举。它将响应式流的概念具象化到网络层面,支持线上传输的背压。我喜欢 RSocket。当然,Spring Framework 和 Spring Boot 本身就内置了对 RSocket 的新支持,此外还有 Spring Security 和 Spring Batch 的支持。
RSocket 是我们与阿里巴巴、Facebook 和 Lightbend 共同捐赠给新兴的 Reactive Foundation 的第一个项目。它目前比 HTTP/2 或 gRPC 更好,仅凭这一点就应该引起您的好奇心,但我对未来同样感到兴奋。最令人兴奋的前景之一是 Spring 团队和其他人一直在努力开发的新 RSocket Broker。这个 Broker 可以取代一些服务注册中心(如 Netflix Eureka)、消息总线(如 RabbitMQ)的用例。RSocket JVM 客户端使用 Reactor,这赋予了它超能力:轻松的重试、错误处理、背压等。
Facebook 和阿里巴巴等组织已经在大规模使用它,而 Spring 使其比以往任何时候都更容易使用。我迫不及待地想看看未来几周、几个月和几年,人们会用 RSocket 构建出什么。
我一直非常兴奋的最后一件事是 Spring 最新版本与 Java 和 Kotlin 最新版本的深度集成。Spring Boot 每六个月发布一次,与 Java 的发布节奏很好地保持一致。使用 Spring Boot 和 Java 15 简直是**梦想成真**。我制作了一个关于 Java 14 的视频,其中介绍了该版本中的大量新特性,包括许多**预览**特性。但您甚至不需要去看所有那些。只需看看 Java 15 中开箱即用的东西就行了!多行文本字符串和 var
本身就让生活轻松多了。新版本的 Java 非常出色,更不用说过去几代版本中所有那些幕后的改进,它们让 Java 更快、更健壮、更适合容器、更安全等等。
我正在使用一台新潮的 Apple Silicon M1 MacBook Pro,并使用 Microsoft OpenJDK 支持 ARM 芯片的版本。它**太快了**。我的大多数应用程序启动时间都在 0.8 秒左右!记住,这些芯片才在几个月前发布!微软/Azul Systems 已经推出了 OpenJDK 的可用移植版本,这证明了生态系统的活力。Java 是一项出色的技术,也是一个更出色的社区,我热爱 Java。
今年对我来说另一个亮点是 Kotlin。今年早些时候我成为了 Kotlin Google Developer Expert,所以我的看法可能带有一些偏见。Kotlin 有协程(coroutines)的概念。Kotlin 中的协程是一个语言关键字,它允许您标记一段特定的代码正在执行一个异步操作,其线程可以由运行时重新调度。这非常简单。Spring 基于这一机制,通过协程集成了响应式编程。因此,您可以在这里获得两全其美的体验:简单的命令式编程风格,同时受益于响应式代码的非阻塞特性。只要 Spring 支持响应式 API,Spring 和 Kotlin 现在都支持协程。
我的朋友们,希望你们能理解 2020 年所蕴含的机遇。我期待在新的一年里与大家交流。而且谁知道呢,也许在科学和后勤允许的情况下,我们还能见面。(向医生们致敬!)新的一年一定会充满乐趣。我希望大家都照顾好自己,保持社交距离,戴好口罩等等,我相信我可以代表整个 Spring 团队祝您和您的家人**新年快乐**!