Spring 5.0 M1 的響應式程式設計

工程 | Rossen Stoyanchev | 2016年7月28日 | ...

正如 Juergen 在他的 Spring Framework 5 M1 釋出公告中提到的,我們的 Spring Reactive 倡議已合併到 Spring Framework 主體中,保留了所有貢獻及其一年多的完整歷史記錄。

它是什麼?

簡而言之,響應式程式設計是指非阻塞、事件驅動的應用程式,這些應用程式透過少量執行緒進行擴充套件,並將背壓(backpressure)作為關鍵組成部分,以確保生產者不會壓垮消費者。Reactive Streams 規範(Java 9 也已採用)使得在不同提供商的層和庫之間進行需求通訊成為可能。例如,一個向客戶端寫入資料的 HTTP 連線可以將它的寫入可用性一路向上遊傳遞給從資料庫獲取資料的資料儲存庫,這樣如果 HTTP 客戶端很慢,儲存庫也可以放慢速度甚至暫停。有關響應式程式設計的更廣泛介紹,請參閱 Dave Syer 的系列文章“響應式程式設計筆記”

從命令式邏輯切換到非阻塞方式時,一個實際挑戰是如何組合非同步邏輯而不會陷入“回撥地獄”。我們需要的那種 API 的一個好例子是 Java 8 中的 CompletionStageStream API。然而,Stream 實際上是為集合構建的,不太適合我們非阻塞 I/O 和事件驅動應用程式中經常遇到的無限或延遲敏感序列。Reactor 及其即將釋出的 3.0 GA 版本是 Reactive Streams 的一個實現,它透過 FluxMono API 型別擴充套件了 Reactive Streams Publisher,提供了類似於 Java 8 Stream 的宣告式組合 API,但功能更廣泛,與 ReactiveX 模式更具可比性。有關此內容的更多資訊,請參閱 Sebastien Deleuze 的“理解響應式型別”

內容包括什麼?

Spring Framework 5 採用了 Reactive Streams 和 Reactor,用於自身的響應式用途以及許多核心 API。M1 版本提供了 JSON (Jackson) 和 XML (JAXB) 的響應式序列化和反序列化、支援 @Controller 程式設計模型的響應式 Web 框架以及響應式 WebClient。這使得支援微服務、分散/收集、資料攝取等場景的輸入和輸出流變得容易。

下面是一個控制器,它以完全非阻塞和響應式的方式從遠端伺服器獲取和流式傳輸資料

@GetMapping("/accounts/{id}/alerts")
public Flux<Alert> getAccountAlerts(@PathVariable Long id) {

  return this.repository.getAccount(id)
      .flatMap(account ->
          this.webClient
              .perform(get("/alerts/{key}", account.getKey()))
              .extract(bodyStream(Alert.class)));
}

支援它的響應式棧是什麼?Spring Web Reactive 位於新的 spring-web-reactive 模組中,與現有的(並且很受歡迎!)位於 spring-webmvc 模組中的 Spring Web MVC 相鄰。這兩個模組共享許多演算法和機制,但實際上不能共享任何程式碼。這是因為 Spring Web Reactive 執行在 Reactive Streams HTTP 介面卡層上,該層從頭到尾都是完全非阻塞和響應式的,一直到 HTTP 執行時。因此,雖然 Spring MVC 是為 Servlet 容器構建並執行在其上,但 Spring Web Reactive 也可以在非 Servlet 執行時(例如 Netty 和 Undertow)上執行。

Spring Web Reactive 與 Spring Web MVC 對比

您可能會想,Spring Framework 團隊如何看待這兩個框架,我們推薦您使用哪個?首先,我們力求在合理範圍內實現最大程度的一致性。@Controller 程式設計模型與響應式方式之間沒有根本性的不相容之處。這一切都取決於底層如何支援該模型,因此表面上沒有任何區別,除了完全支援來自 RxJava 的 FluxMono 以及 ObservableSingle 等響應式型別,用於輸入和輸出。

Spring Web Reactive 比 Spring MVC 更好嗎?Spring Framework 響應式支援的最大價值主張和我們的獨特之處在於,我們不會拋棄現有應用程式。在 Spring 5 中,傳統的 Spring MVC 繼續在任何 Servlet 3.1 棧上執行,包括 Java EE 7 伺服器。對於 Spring Web Reactive,我們支援 Tomcat、Jetty、Undertow 和 Netty,並且可以適應任何 Servlet 3.1 容器,而不會妥協。我們計劃在共享演算法和機制方面繼續保持 Spring MVC 和 Spring Web Reactive 之間的協同作用,以便在上層支援相同的程式設計模型。Spring MVC 方面的改進請求或錯誤報告將使 Spring Web Reactive 受益,反之亦然。

這意味著您作為開發人員可以選擇最適合您目的的方式。如果有人告訴您同步或阻塞是邪惡的,請不要理會。它們並非如此,實際上這是一個權衡。命令式邏輯易於編寫和除錯。當然,它的伸縮性或效率不如響應式,但這正是權衡所在。總有許多情況下,命令式對於手頭的任務來說完全沒問題,而在另一些情況下,響應式和非阻塞是必需的。在微服務場景中,您甚至可以為每個獨立服務選擇實現風格,所有這些都在同一個一致的程式設計模型下進行。

試一試

更多詳細資訊和入門指南,請參閱 Spring Boot 響應式 Web 啟動器和參考文件中的新章節

最後但同樣重要的是,我希望您能參加我們的 SpringOne Platform 2016 大會,屆時我們將有關於此主題的主題演講和眾多分會。拉斯維加斯見!

獲取 Spring 時事通訊

透過 Spring 時事通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您快速提升。

瞭解更多

獲取支援

Tanzu Spring 透過一個簡單的訂閱提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視全部