作者:Dubbo 社区

Dubbo 简介

Apache Dubbo 是一款 RPC 服务开发框架,用于处理微服务架构下的服务管理与通讯问题,官方供给了 Java、Golang 等多语言 SDK 完结。运用 Dubbo 开发的微服务原生具备相互之间的长途地址发现与通讯能力, 利用 Dubbo 供给的丰富服务管理特性,可以完结诸如服务发现、负载均衡、流量调度等服务管理诉求。Dubbo 被设计为高度可扩展,用户可以便利的完结流量阻拦、选址的各种定制逻辑。

背景

Spring Framework 6.0 于 11 月 16 日正式发布 GA 版别,Spring Boot 3.0 也于11月25日正式发布 GA 版别,而且 Spring 6 & SpringBoot 3 最低支撑 JDK17,意味着假如晋级运用 Spring 6 & Spring Boot 3 时就必须需求晋级运用 JDK17。

可是Java 8 现在是国内干流生产环境 Java 版别之一。尽管近几年陆续发布了 Java 11、Java 17 官方 LTS 版别,可是大部分开发者仍然本着 “你发任你发,我用 Java8” 的看法看待JDK的晋级。不过 Java 17 版别在性能上确实做了很多的优化特别是 ZGC 的发布,促进了国内不少企业晋级到 Java 17。

而 Spring 框架在 Java 生态中的重要程度显而易见,咱们相信在 Spring 这波“最低支撑 JDK17” 推进下,Spring Framework 6.0 & Spring Boot 3.0 一定会在不久的将来被大家接受,并成为干流技能栈。

Dubbo 社区非常重视 Spring 社区的更新迭代,总会积极支撑适配,这点在最近 Spring 6.0 和 Spring Boot 3.0 发布中同样得到了验证。Dubbo 社区早在 Spring 6.0.0-RC4 和 Spring Boot 3.0.0-RC2 时已经做好了大致的兼容适配,可是为了保证 Dubbo 可以完全适配 Spring 6 和 Spring Boot 3.0 的正式版,咱们一向比及 Spring Boot 3.0 GA 后,才选择宣告这个令人高兴的事情。

为什么要晋级到 Spring 6.0 & Spring Boot 3.0

首先是,晋级到 Spring 6.0 & Spring Boot 3.0 将获得未来很长年限的由官方供给的免费技能支撑。Spring 6 和 Spring Boot 3 是 Spring 下一代技能框架柱石,尽管官方当时同时维护了 Spring 5.3 和 Spring Boot 2.6.x 和 Spring Boot 2.7.x,但它们最终都会在 2025 年和 2026 年结束其 OSS support(Open Source Software Support)。

其次是,您将在新一代框架中获得很多新特新,这些新特性都可以在Spring Boot 3.0 Release Notes [ 1] 和What’s New in Spring Framework 6.x [2 ] 中获得。

最终是,Spring 6.x 和 Spring Boot 3.x 将会最广泛的支撑 JDK 17-29,需求额外说明的是 JDK17 作为当时最新的 LTS 版别,它供给了一组累积的最新语言、API 和 JVM 增强功能,使其成为更具吸引力的编译版别的晋级,这也是为什么最低支撑 JDK17 的原因。

Dubbo 支撑 Spring 6 & Spring Boot 3

现在很高兴向大家宣告,Dubbo 已经开始兼容 Spring 6 & Spring Boot 3,所以当时 Dubbo 3.2.0-beta.3版别可以同时兼容支撑 Spring Boot 1.x、2.x、3.x。您现在可以运用dubbo-3.2.0-beta.3版别体验其兼容性。

<dependency>
  <groupId>org.apache.dubbo</groupId>
  <artifactId>dubbo-spring-boot-starter</artifactId>
  <version>3.2.0-beta.3</version>
</dependency>

更多关于 Spring Boot 3.0 集成 Dubbo 运用示例可拜见 apache/dubbo-sample:

github.com/apache/dubb…

晋级总结

咱们根据 Dubbo 兼容适配 Spring 6 & Spring Boot 3 过程中总结的经验整理如下,其他组件维护者也可以参阅以下经验进行适配或许晋级,更早适配晋级到最新版别:

Jakarta EE

Jakarta EE 9 将一切API包名从javax.*命名空间变更到了jakarta.*。而形成这一改变的原因是 Oracle 拒绝交出相关权益,概况可以检查:

www.oschina.net/news/106465…

由于 Jakarta EE 的搬迁,对于 Web Apps,保证晋级运用 Tomcat 10, Jetty 11, or Undertow 2.2.19。

以下列出了一系列工具可以帮助你完结这部分的搬迁:

  • OpenRewrite recipes [3 ] .
  • The Spring Boot Migrator project [4 ] .
  • Migration support in IntelliJ IDEA [5 ] .

移除 META-INF/spring.factories 文件对 Auto-configuration 的支撑

Spring Boot 3.0 移除了 META-INF/spring.factories 文件对 Auto-configuration 的支撑,为了兼容性,SpringBoot 2.7.x 是最终一个支撑的版别。

适配支撑依照下面两个过程即可完结

Step1:[可选] 运用 @AutoConfiguration注解替代@Configuration(proxyBeanMethods= false)

@AutoConfiguration 注解是 SpringBoot 2.7 中的新引入的注解,旨在专门标识 Auto-configuraton class name。

仍然运用@Configuration注解标识自动适配类也是可以的,Dubbo 正是根据这个便利点完美支撑了 Spring Boot 1.x、2.x、3.x 一切版别。

Step2:运用 AutoConfiguration.imports 文件替代 META-INF/spring.factories 文件

Spring Boot 2.7 是最终一个仍然兼容运用 spring.factories 的版别,SpringBoot 3 以后不再兼容,此时您应该运用META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件替换。

在该文件罗列你一切的 configuration classes,每行一个 class name,例如:

com.mycorp.libx.autoconfigure.LibXAutoConfiguration
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration

为了对齐 ISO-8601,运用 yyyy-MM-dd’T’HH:mm:ss.SSSXXX 作为默许日志日期格局

本来默许日志日期格局:yyyy-MM-dd HH:mm:ss.SSS
当时默许日志日期格局:yyyy-MM-dd’T’HH:mm:ss.SSSXXX

本来的默许日志日期格局不具有 timezone / offset 信息。

yyyy-MM-dd'T'HH:mm:ss.SSSXXX >>> e.g.: 2014-12-03T10:06:04.646+08:00

移除 YamlJsonParser

Spring Boot 官方测试发现 YamlJsonParser 并不能很好的解析 JSON,Spring Boot 3 决议不再支撑运用它来作为解析 JSON 的备选。

YamlJsonParser 封装的是 snakeyaml。

Spring Boot 3 解析 JSON 的解析器运用优先级如下:

  • 1)JacksonJsonParser
  • 2)GsonJsonParser
  • 3)BasicJsonParser

移除 spring.session.store-type 装备键

移除了spring.session.store-type装备项,当存在多个可用存储库,将会依照 Redis,JDBC,Hazelcast,Mongo 次序运用。

更新 Spring data 装备键使其清楚地反应该装备键是否依靠 Spring Data

假如存储库(redis、mongo 等)相关的装备键不依靠 Spring Data 存在,则只需求 spring 前缀,否则需求运用 spring.data 前缀。

举例说明:

spring.redis.host >> spring.data.redis.host
spring.redis.port >> spring.data.redis.port
spring.data.cassandra.port >> spring.cassandra.port

重构 HttpMethod 枚举为类

根据最新的rfc2616 [6 ] ,HTTP Method 已经归于不可枚举属性,所以重构 HttpMethod enum 类为 class 类。

除了咱们熟知的 GET, HEAD, PUT, POST 等办法,现在还存在了可扩展办法,当时可扩展办法包含了 LOCK, COPY, 和 MOVE。这些扩展办法定义在 WebDAV。

不答应 URI 尾部斜杠匹配

Spring 6 之前,拜访 “/resources” 和 “/resources/” 都可以进入 resources() 办法。

@GetMapping("/resources")
String resources() {
    return "Hello from /resources";
}

Spring 6 之后,您只能经过看到的 path “/resources” 进入 mapping 办法。

假如您仍然想让“/resources/” 和 “/resources” 进入相同的 mapping 办法,可以经过其他手法,诸如“反向署理”、“Servlet/Web 过滤器”或“在控制器装备显式重定向”。

供给根据 @HttpExchange 服务接口的 HTTP 客户端

Spring 6 介绍了@HttpExchange注解,根据 @HttpExchange 注解可以简化 HTTP 长途调用。

增强 Spring SPI 加载器 SpringFactoriesLoader 答应加载多自定义文件

Spring 6 之前,SpringFactoriesLoader 只答应加载”META-INF/spring.factories”文件内容。

Spring 6 之后,SpringFactoriesLoader 可以加载自定义文件或文件名文件,而且可以经过链式编程加载多个文件。

早期兼容 JDK19 预览版的虚拟线程(virtual threads)

可以在 Spring 6 和 Spring Boot 3 中运用虚拟线程处理恳求来提早体验。

这部分具体说明拜见:

spring.io/blog/2022/1…

支撑 RFC 7807 Problem Details

Spring 6 以后,Spring MVC 可以运用 application/problem+json media 类型自定义 错误信息呼应体,像下面这样:

{
  "type": "https://example.org/problems/unknown-project",
  "title": "Unknown project",
  "status": 404,
  "detail": "No project found for id 'spring-unknown'",
  "instance": "/projects/spring-unknown"
}

展望

在云原生年代,Java 的跨平台特性,已经不算是其亮眼特性了,而其 Jar 包体积大、发动慢、占用内存多、需求另装 JVM 是 Java 运用的痛点问题。

而经过运用 GraalVM 可以很好的处理这些问题。而且经过 GraalVM 的 AOT(Ahead-Of-Time)可以将运用编译成单独可执行文件并直接运转。

未来 Dubbo 将会积极地在 Native 方面做一些工作以此可以使运用程序达到下面的目标:

  • 支撑 Spring & Spring Boot native-image
  • 较小的本地运用程序和容器镜像占用空间
  • 快速发动,快速发动(几十毫秒)
  • 低内存耗费,削减 RSS(驻留集大小),低内存有助于优化需求多个容器的微服务架构部署中的容器密度
  • 快速的第一恳求呼应,避免 Hotspot 的预热问题

相关链接

[1] Spring Boot 3.0 Release Notes:

github.com/spring-proj…

[2] What’s New in Spring Framework 6.x:

github.com/spring-proj…

[3]OpenRewrite recipes

docs.openrewrite.org/reference/r…

[4]The Spring Boot Migrator project

github.com/spring-proj…

[5]Migration support in IntelliJ IDEA

blog.jetbrains.com/idea/2021/0…

[6] rfc2616

datatracker.ietf.org/doc/html/rf…