1. 程式人生 > >實戰SpringCloud響應式微服務系列教程(第三章)

實戰SpringCloud響應式微服務系列教程(第三章)

接著之前的:

實戰SpringCloud響應式微服務系列教程(第一章)

實戰SpringCloud響應式微服務系列教程(第二章)

1.1.3Reactor框架

響應式程式設計是一種程式設計模型,本節將介紹這種程式設計模型的具體實現工具 Project Reactor框架。 Reactor框架也是 Spring5中實現響應式程式設計採用的預設框架。

Project Reactor: https://projectreactor.io/

1.1.4響應式程式設計實現技術概述

響應式程式設計就是利用非同步資料流進行程式設計,本質上就是觀察者( Observer)模式的一種表現形式。本節首先討論實現非同步操作的幾種常見方式,然後引出響應式程式設計的主流實現技術。

1.實現非同步操作的常見方式

在Java中,為了實現非同步非阻塞,一般會採用回撥( Callback)和 Future這兩種機制,但這兩種機制都存在一定侷限性。

(1)回撥

回撥的含義如圖所示,即類A的 method A()方法呼叫類B的 method B()方法,然後類B的 methodB()方法執行完畢後再主動呼叫類A的 callback()方法。回撥體現的是一種雙向的呼叫方式。

可以看到,回撥在任務執行過程中不會造成任何阻塞,任務結果一且就緒,回撥就會被執行。但我們也應該看到在使用回撥機制時,程式碼會從一個類中的某個方法跳到另一個類中的某個方法,從而造成流程的不連續性。對於單層的非同步執行而言,回撥很容易使用。

但是對於巢狀的多層非同步組合而言,就顯得非常笨拙。所以回撥很難大規模地組合起來使用,因為很快就會導致程式碼難以理解和維護,即形成所謂的“回撥地獄( Callback Hell)”問題。

(2) Future

可以把 Future模式簡單理解為這樣一種場景:有一個希望處理的任務,把這個任務提交到 Future, Future就會在一定時間內完成這個任務,而在這段時間內我們可以去做其他事情。

作為 Future模式的實現,Java中的 Future介面只包含如下5個方法

public interface Puture<v>{
   boolean cancel (boolean mayinterrupt Ifrunning):
   boolean iscancelled
   boolean isdone ():
   V get() throws Interruptedexception, Executionexception;
   V get (long timeout, Timeunit unit)?
      throws Interruptedexception, Executionexception, Timeoutexception
}

Future介面中的 cancel方法用於取消任務的執行; iscancelledo方法用於判斷任務是否已經取消;兩個get()方法會等待任務執行結束並獲取結果,區別在於是否可以設定超時時間,最後 isDone()方法判斷任務是否已經完成。

Future雖然可以實現獲取非同步執行結果的需求,但是它沒有提供通知機制,我們無法得知 Future什麼時候完成。為了獲取結果,我們要麼使用阻塞的兩種get()方法等待 Future結果的返回,這時相當於執行同步操作;

要麼使用 isDone方法輪詢地判斷 Future是否完成,這樣會耗費CPU資源。所以, Future適合單層的簡單呼叫,對於巢狀的非同步呼叫而言同樣非常笨重,不適合複雜的服務鏈路構建。

鑑於Future機制存在的缺陷,Java8中引入了 Completablefuture 機制。 Completablefuture在一定程度上彌補了普通 Future的缺點。在非同步任務完成後,我們使用任務結果時就不需要等待,可以直接通過 thenaccept()、 thenApply()、 thencompose()等方法將前面非同步處理的結果交給另外一個非同步事件處理執行緒來處理。

Completablefuture提供了非常強大的 Future擴充套件功能,可以幫助我們簡化非同步程式設計的複雜性,並且提供了函數語言程式設計的能力,可以通過回撥的方式處理計算結果,也支援轉換和組合 Completablefuture所提供的各種方法。

對日常開發工作而言,大多數時候我們是在處理簡單的任務,這時使用 Completablefuture確實可以滿足需求。但是,當系統越來越複雜,或者我們需要處理的任務本身就非常複雜時,Completablefuture對於多個處理過程的組合仍然不夠便捷。使用 Completablefuture編排多個Future是可行的,但並不容易。我們會擔心寫出來的程式碼是否真的沒有問題,而隨著時間的推移,這些程式碼會變得越來越複雜和難以維護。為此,我們需要引入響應式程式設計的相關技術和框架,這些技術和框架能夠支援未來更輕鬆地維護非同步處理程式碼。

2.響應式程式設計的主流實現技術

目前,響應式程式設計的主流實現技術包括 Rxjava、 Akka Streams、Vert.x和 Project Reactor等。

(1)Rxjava

Reactive Extensions(Rx)是一個類庫,它集成了非同步基於可觀察( Observable)序列的事件驅動程式設計,最早應用於微軟的NET平臺。而 Rxjava是 Reactive Extensions 的Java實現用於通過使用 Observable/ Flowable序列來構建非同步和基於事件的程式庫,目前有1x版本和2.x版本兩套實現。

Rxjava1.x誕生於響應式流規範之前,雖然可以和響應式流的介面進行轉換,但是由於底層實現的原因,使用起來並不是很直觀。 Rxjava2在設計和實現時考慮到了與現有規範的整合,按照響應式流規範對介面進行了重寫,並把1.x版本中的背壓功能單獨分離出來。但為了保持與 Rxjava1x的相容性, Rxjava2在很多地方的使用也並不直觀。關於 Rxjava的更多內容,可參考官網(http://reactivex.io/),我們這裡不做過多介紹。

(2)Akka Streams

Akka執行在JVM上,是構建高併發、分散式和高彈性的訊息驅動應用程式的一個工具件。 Actor是Akka中最核心的概念,它是一個封裝了狀態和行為的物件,Actor之間可以通過交換訊息的方式進行通訊。通過 Actor能夠簡化鎖及執行緒管理,可以非常容易地開發出正確的併發程式和並行系統。

Akka也是響應式流規範的初始成員,而 Akka Streams是以Aka為基礎的響應式流的實現,在Akka現有的角色模型之上提供了一種更高層級的抽象,支援背壓等響應式機制。

(3) Vertx

Vert. x是 Eclipse基金會下的一個開源的Java工具,是一個非同步網路應用開發框架,用來構建高併發、非同步、可伸縮、多語言支援的Web應用程式。Vert.x就是為了構建響應式系統而設計的,基於事件驅動架構, Vert x實現了非阻塞的任務處理機制。

verx中包含Vert.x Reactive Streams工具庫,該工具庫提供了Vver.x上響應式流規範的實現。我們可以通過 Vert x提供的可讀流和可寫流處理響應式流規範中的釋出者和訂閱者。

(4) Project Reactor

Spring S中引入了響應式程式設計機制,而 Spring5中預設集成了 Project Reactor作為該機制的實現框架。 Reactor誕生較晚,可以認為是第二代響應式開發框架。

所以,它是一款完全基於響應式流規範設計和實現的工具庫,沒有 Rxjava那樣的歷史包,在使用上更加直觀、易懂。但從設計理念和API的表現形式上, Reactor與 Rxjava比較類似,可以說 Reactor基於響應式流規範,但在API方面又儘可能向 Rxjava靠攏。

Flux和Mono是 Reactor中的兩個核心元件,Flux代表包含0到n個元素的非同步序列,而Mono則表示0個或者一個元素的序列。Reactor框架使我們討論的重點,下一節我們將從Reactor框架的引入具體講解Flux和Mon