天天看點

10分鐘讓程式員快速擁有響應式Web實戰經驗,終于可吊打面試官了

作者:程式員進階碼農II

響應式Web實戰經驗

介紹完Spring Boot所提供的針對響應式Web服務的功能特性,接下來,讓我們看看在應用程式中如何充分利用這些功能特性。

使用非阻塞式Web服務提升系統性能

一直以來,SpringWebMVC是我們開發Web服務的主流架構。

但要注意的是,盡管Servlet本身在新版本中提供了異步非阻塞的通信機制,但SpringWebMVC在實作上并不允許在整個請求的生命周期中都采用非阻塞式的操作方式。

是以,Spring在盡量沿用原有的開發模式以及API設計的基礎上提供了支援異步非阻塞的Spring WebFlux架構。WebMVC和WebFlux的本質差別在于它們對請求的處理模型不同。

我們知道,WebMVC建立在阻塞I/O之上。

這意味着處理每個請求的Thread可能被從I/O讀取傳入消息體阻塞。相比之下,WebFlux建構在非阻塞API之上,這意味着沒有操作需要與I/O阻塞線程進行互動。

通過簡單的原理分析,我們明确了使用WebFlux所提供的非阻塞式Web服務能夠提高系統的性能。為了驗證這一分析結果,我們可以通過執行測試用例來提供量化名額和資料。這裡直接引用《Spring響應式程式設計》一書中的測試結果,圖5-7展示了WebFlux與WebMVC吞吐量測量結果。

10分鐘讓程式員快速擁有響應式Web實戰經驗,終于可吊打面試官了

圖5-7 WebFlux與WebMVC吞吐量測量結果比較

而圖5-8則展示了WebFlux和WebMVC的延遲對比結果。

10分鐘讓程式員快速擁有響應式Web實戰經驗,終于可吊打面試官了

圖5-8 WebFlux和WebMVC的延遲對比

在圖5-7和圖5-8中,“+”線代表WebMVC,“-”線代表WebFlux。通過對比,我們不難得出結論,WebFlux在降低吞吐量和減少系統延遲方面比WebMVC更高效。具體的測試結果可以進一步參考《Spring響應式程式設計》。

建構全棧響應式服務體系

針對響應式程式設計技術棧,有一點需要注意,即響應式程式設計并不是隻針對系統中的某一部分元件,而是要适用于調用鍊路上的所有元件。所謂的全棧響應式程式設計,具體指的是響應式開發方式的有效性取決于是否在整個請求鍊路的各個環節都采用了響應式程式設計模型,如圖5-9所示。

10分鐘讓程式員快速擁有響應式Web實戰經驗,終于可吊打面試官了

圖5-9 全棧響應式程式設計示意圖

在圖5-9中,如果某一個環節或步驟不是響應式的,就會出現同步阻塞,進而導緻響應式資料流無法正常運作。如果某一層元件(例如資料通路層)無法采用響應式程式設計模型,那麼響應式程式設計的概念對于整個請求鍊路的其他層而言就沒有意義。

本章關注的是Web服務和網絡協定。事實上,從Spring Boot 2開始,對于支援響應式通路的各種資料庫,Spring Data都提供了響應式版本的Repository。

目前,Spring Data Reactive Repository支援MongoDB、Cassandra、Redis、Couchbase等多款主流的NoSQL資料庫。Spring Data項目有幾個單獨的子產品,逐個對這些NoSQL資料庫提供了響應式的資料通路支援。

我們在前面的案例中,已經看到了針對MongoDB的ReactiveMongoRepository。在使用方式上,響應式Spring Data Repository和普通的Repository是完全一緻的。

這裡特别強調一點,在常見的Web服務架構中,最典型的非響應式場景就是在資料通路層中使用關系型資料庫。對關系型資料通路過程的響應式改造一直是技術難點,但Spring Data團隊還是做出了很多嘗試工作,并最終開發了R2DBC規範。

R2DBC是Reactive Relational DataBase Connectivity的簡稱,即響應式關系資料庫連接配接。

該規範允許驅動程式提供與資料庫的完全響應式和非阻塞內建。

Spring Data同樣采用了R2DBC規範,并孵化了另一個獨立元件SpringData R2DBC。圖5-10展示了JDBC規範與R2DBC規範的對應關系以及所涉及的技術棧。

10分鐘讓程式員快速擁有響應式Web實戰經驗,終于可吊打面試官了

圖5-10 Spring Data JDBC和Spring Data R2DBC

類似地,這裡也給出一個使用Spring Data R2DBC的示例代碼,如代碼清單5-43所示。

代碼清單5-43 擴充R2dbcRepository接口實作代碼

public interface ReactiveUserRepository extends R2dbcRepository<User,

Long> {

@Query("insert into USER (USER_CODE, USER_NAME) values

(:userCode,:userName)")

Mono<Boolean> addUser(String userCode, String userName);

@Query("SELECT * FROM USER WHERE id =:id")

Mono<User> getUserById(Long id);

}

可以看到,ReactiveUserRepository擴充了Spring Data R2DBC所提供的R2dbcRepository接口,然後使用@Query注解分别定義了一個查詢和插入方法。

RSocket替代HTTP

在Java領域中,RSocket協定的應用越來越廣泛。Spring Boot、SpringCloud以及Dubbo等主流開發架構都內建了RSocket協定。

Dubbo在3.0.0-SNAPSHOT版本基于RSocket協定對響應式程式設計提供了支援,使用者可以非常友善地使用RSocket的文法。對Spring家族而言,Spring 5.2也把RSocket作為内置的通信協定,而随着Spring Boot 2.4的釋出,Spring對RSocket的支援日漸完善。

一定程度上,可以把RSocket看作對HTTP等其他協定的一種替代。REST的最大特點是它與HTTP強關聯,這是優勢也是劣勢。優勢在于基于RESTful風格開發的Web API易于調試,而劣勢在于其互動模式過于單一,隻支援請求-響應式。在微服務大行其道的當下,RSocket專為服務互動而設計。它是一種面向連接配接的消息驅動協定,在應用程式級别内置了資料流控制機制。它既可以在浏覽器中使用,也可以在伺服器上使用。

響應式Web面試題分析

面試題1:響應式程式設計模型和普通程式設計模型的本質差別是什麼?

答案:本質上,我們認為普通程式設計模型執行的是一種同步阻塞式的操作,而響應式程式設計模型則為開發人員提供了異步非阻塞式的程式設計體驗。這個說法在面試過程中是沒有問題的,但顯然比較單薄和缺乏個人見解。我們可以從資料流的角度切入來看待這個問題。在傳統的方法調用中,用戶端和伺服器端之間的資料流向是一種“拉”模式,即服務端被動接收用戶端請求并傳回資料。與之對應的,如果資料主動從伺服器端流向用戶端,那麼就是一種“推”模式。而從響應式流規範的定義來看,我們可以明确響應式程式設計介于這兩者之間,是一種推-拉結合的資料流模式,進而避免出現純拉模式下的系統瓶頸,以及純推模式下的流量控制問題。這樣的回答思路和方式在面試過程中更加能夠擷取面試官的認同。

面試題2:你能描述響應式程式設計技術的具體應用場景嗎?

答案:響應式程式設計的異步非阻塞式特性在日常開發過程中有廣泛的應用場景。首先就是資料流處理,典型的案例包括日志埋點、服務運作時的狀态采集等。其次,我們在高并發場景中也可以使用響應式程式設計技術,因為響應式程式設計所具備的異步非阻塞式I/O模型非常适合對并發流量進行高效處理。針對這個面試題,我們可以列舉響應式程式設計的具體應用案例,像NetflixHystrix就使用RxJava來實作了滑動視窗機制,進而高效完成了對服務調用結果的分析和統計;而Spring家族自建的Spring Cloud Gateway則使用ProjectReactor實作了響應式API網關。

面試題3:Spring架構為開發人員提供了哪些響應式程式設計元件?

答案:這道題基本屬于送分題,你隻要對Spring 5架構有基本的了解,相信都能應答自如,畢竟響應式程式設計是該架構引入的最大的功能特性。

Spring 5分别針對Web服務層和資料通路層提供了WebFlux和Reactive SpringData架構。而Reactive Spring Data架構則對MongoDB、Cassandra、Redis、Couchbase等多款主流的NoSQL資料庫提供了響應式程式設計支援。

面試題4:Spring WebFlux和傳統的WebMVC在架構上有什麼差別和聯系?

答案:從架構設計上講,Spring作為一套內建性和擴充性很強的開源架構,針對不同的Web層元件,盡量采用了相同的元件命名和實作政策。例如,在WebFlux和WebMVC中,都存在HandlerMapping和HandlerAdapter等同名的程式設計元件。開發人員也可以使用傳統的@RestController、@RequestMapping等注解來同時開發基于WebMVC和WebFlux的Web服務。這是兩者之間的聯系。

而差別也很明确,主要展現在對請求的處理模型上。本章專門對兩者處理模型的原理和效果做了深入分析,你可以參考文中的描述來進行回答。

面試題5:為什麼要引入RSocket協定,和HTTP相比該協定有哪些優勢?

答案:這道題考查你在新技術上的知識面廣度。RSocket是一款2015年才出現的網絡通信協定,和HTTP相比還很年輕,但卻有取而代之的趨勢。原因就在于HTTP本身的請求-響應式互動過程過于單一,無法滿足多樣化的請求處理場景。而RSocket則提供了額外的請求-響應流、即發-即忘和通道這三種新的互動模式,并且能夠與響應式程式設計技術完美整合。是以,無論是互動方式上還是性能上,它都比HTTP更有優勢。

面試題6:所謂全棧式響應式技術體系指的是什麼?通過Spring架構我們如何做到全棧響應式?

答案:圍繞響應式程式設計模型,我們需要明确全棧響應式程式設計這一概念,其背後的設計思想就是請求從Web服務層到業務邏輯層再到資料通路層,整個調用鍊路中都應該以響應式資料流的方式進行互動,也就是說方法調用傳回值都應該是Mono或Flux對象。在Spring中,普通的業務邏輯層元件可以直接使用Project Reactor架構來內建響應式程式設計技術,針對Web服務開發可以使用WebFlux,針對網絡通信可以使用Spring RSocket,而針對資料通路則可以使用Reactive Spring Data。特别需要強調一下的是,當下關系型資料庫仍然是大多數業務系統的基石,而針對關系型資料庫通路,Spring也專門開發了Spring Data R2DBC架構。

本文給大家講解的内容是springweb服務應用響應式Web開發元件:響應式Web實戰經驗

  • 下文給大家講解的是springboot内置緩存:打造高性能系統緩存,緩存注解

繼續閱讀