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

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

接上一篇:

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

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

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

1.1.4 引入Reactor框架

如果想在程式碼中整合 Reactor框架,則需要新增如下的 Maven依賴,分別引入 Reactor的核心功能以及用於支援測試的相關工具類。

<dependency>
    <groupid>io.projectreactor</groupid>
    <cartifactid>reactor-cores/artifactid>
</dependency>
<dependency>
   <groupid>io.projectreactor</groupid>
   <cartifactid>reactor-tests/artifactid>
   <scope>test</scope>
</dependency>

 

Reactor框架在實現響應式流規範的基礎上有其特定的設計思想。本節先介紹 Reactor框架的非同步資料序列,然後介紹Flux和Mono這兩個核心元件。

1. Reactor非同步資料序列

當使用 Reactor開發響應式應用程式時,無論採用何種操作符,都將得到一個如圖所示的非同步資料序列。

onNext x 0..N [onError |onComplete]

以上公式包含三種不同型別方法的呼叫,分別處理不同場景下的訊息通知。

  • onNext():正常的包含元素的訊息通知。

  • onCompleted():序列結束的訊息通知,可以沒有。

  • onError():序列出錯的訊息通知,可以沒有。

按照響應式流規範,當這些訊息通知產生時,非同步序列的訂閱者中對應的這三個方法將被呼叫。如果序列沒有出錯,則 onerror()方法不會被呼叫;如果不呼叫 onComplete()方法,就會得到一個無限非同步序列。通常,無限非同步序列應該只用於測試等特殊場景。

2.Flux元件

Flux代表0至N個元素的非同步序列,如下圖,序列的三種訊息通知都是用於Flux.

以下程式碼示例展示了在具體專案中使用Fux元件的方法。如果我們瞭解微服務架構中基於 Hystrix I的服務回退( Fallback)機制,就應該知道程式碼中的 getordersfallbacko是一個典型的回退函式,我們通過FIux.fromlterableo方法構建了 Flux<Order>

物件,作為回退函式的返回值。

關於服務回退機制,將在之後章節中具體介紹

private Flux<order> getordersfallback(){
    List<order> fallbacklist = new Arraylist<>();
    Order order= new Order();
    order.setid("orderinvalidid");
    order.setaccountid("Invalidid");
    order.setitem("Order list is not available");
    order.setcreatetime (new Date();
    fallbacklist.add (order);
    return Flux.fromiterable (fallbacklist);
}

 

下面的示例更加容易理解一點,從位於方法名上的@ Getmapping註解可以看出,這是個 Controller中的端點,用於返回一個 Order物件列表。這裡返回的 Order列表同樣通過Flux< Order>物件進行呈現。

@getmapping("/vl/orders")
public Flux<Order> getorderlist(){
    Flux<order> orders= orderservice. getorders();
    return orders;
}

 

3.Mono元件

在 Reactor中,Mono表示包含0個或1個元素的非同步序列,如圖所示,該序列中同樣可以包含與Fux相同的三種類型的訊息通知。

請注意,Mono也可以用來表示一個空的非同步序列,該序列沒有任何元素,僅僅包含序列結束的概念(類似於Java中的 Runnable)。我們可以用Mono<void>代表一個空的非同步序列。

與FIux元件一樣,通過服務回退來演示Mono元件的用法,示例程式碼如下。

private Mono<order> getorderfallback(){
    Order order = new Order();
    order.setid("orderinvalidid");
    order.setaccountid("Invalidid");
    order.setitem("Order list is not available");
    order.setcreatetime(new Date());
    return Mono.just(order);
}

 

這裡首構建一個 Order物件,然後通過 Mono.just()方法返回一個Mono物件。

Controller層元件也是一樣的,通過d獲取Mono<Order>物件的端點示例如下。

@tapping("/vl/orders/{id}")
public Mono<order> getorder(@Pathvariable String id){
    Mono<order> order orderservice.getorderbyid(id);
    return order;
}

 

相較Mono,Flux是更通用的一種響應式元件,所以針對FIux的操作要比Mono更豐富。另一方面,FIux和Mono之間可以相互轉換。例如,把兩個Mono序列合併起來就得到一個Flux序列,而對一個FIux序列進行計數操作,得到的就是Mono對