Apache Dubbo 官方正式釋出 Spring 6 & Spring Boot 3 支援

ApacheDubbo發表於2022-12-23

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-RC4Spring 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 Noteshttps://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes)What's New in Spring Framework 6.xhttps://github.com/spring-projects/spring-framework/wiki/What's-New-in-Spring-Framework-6.x) 中獲得。

最後是,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.2 版本可以同時相容支援Spring Boot 1.x、2.x、3.x。您現在可以使用dubbo-3.2.0-beta.2版本體驗其相容性。

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

更多關於Spring Boot 3.0 整合 Dubbo 使用示例可參見apache/dubbo-sample:https://github.com/apache/dubbo-samples/tree/master/1-basic

升級總結

我們根據Dubbo 相容適配Spring 6 & Spring Boot 3 過程中總結的經驗整理如下,其他元件維護者也可以參考以下經驗進行適配或者升級,更早適配升級到最新版本:

Jakarta EE

Jakarta EE 9 將所有API包名從javax.*名稱空間變更到了jakarta.*。而造成這一變化的原因是Oracle拒絕交出相關權益,詳情可以檢視:https://www.oschina.net/news/106465/oracle-killed-java-ee。

因為Jakarta EE 的遷移,對於Web Apps,確保升級使用Tomcat 10, Jetty 11, or Undertow 2.2.19。

以下列出了一系列工具可以幫助你完成這部分的遷移:

移除META-INF/spring.factories檔案對Auto-configuration的支援

Spring Boot 3.0移除了META-INF/spring.factories檔案對Auto-configuration的支援,為了相容性,SpringBoot 2.7.x 是最後一個支援的版本。

適配支援按照下面兩個步驟即可完成

Step1: [可選] 使用 @AutoConfiguration 註解代替 [@Configuration(proxyBeanMethods ](/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,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 中使用虛擬執行緒處理請求來提前體驗。

這部分詳細說明參見:https://spring.io/blog/2022/10/11/embracing-virtual-threads

支援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 的預熱問題

歡迎在 https://github.com/apache/dubbo 給 Dubbo Star。

相關文章