使用Java EE 8中的反应式API加速服务
服務通常可以通過異步處理進行優化,即使不改變其對外界的行為。
某些服務效率不高的原因是,它們需要等待其他服務提供結果才能繼續下去。
讓我們看一下如何在不等待外部REST服務的情況下調用它們,并獨立進行多個并行調用,然后將它們的結果與Java EE 8中的響應管道結合起來。
如果我們的服務調用了多個微服務,并等待每個調用完成并返回結果,然后再執行另一個調用,那么使用響應式API進行重構是一個不錯的選擇。 為了提高服務效率,如果它們彼此不依賴,則可以并行執行對外部服務的所有調用。 這將減少等待所花費的時間,從而加快微服務的速度。
為了并行調用REST服務,我們將在JAX-RS中使用新的反應式客戶端API。 我們將其與RxJava庫結合起來,以在可用時結合其結果。 這種結合將使我們能夠編寫簡潔高效的代碼。 另一個好處是,可以釋放當前線程以進行進一步處理,同時等待遠程調用的結果。
我們將建立一個管道,在結果到達時對其進行處理,最后將其合并為單個響應。 管道的第一部分將調用每個遠程服務。 除了等待結果,我們將指定處理每個收到的結果并繼續調用其他服務。 在JAX-RS客戶端請求構建器上使用rx()方法可以使我們調用get()方法的版本,該版本將立即返回而不是等待結果。 為了處理結果到達時的結果,我們可以將方法處理程序鏈接到從get()方法的rx版本返回的CompletionStage上:
CompletionStage stage = temperatureServiceTarget.request().rx().get(Temperature.class).thenApply(temperature -> new Forecast(temperature));上面的代碼將調用溫度服務,然后注冊一個lambda表達式,以在到達溫度時對其進行處理。 這會將溫度映射到預測對象,稍后可以使用stage變量進行訪問。
但是,我們希望使用的另一種變體get()方法連同RxJava可流動祈求從澤西島項目獲得Flowable的RxJava而不是CompletionStage 。 與CompletionStage相比, Flowable接口可以更輕松地將多個異步結果與更簡單的代碼組合在一起,并且效率更高。
使用以下代碼,我們將調用外部服務并返回Flowable:
Flowable flowable = temperatureServiceTarget.register(RxFlowableInvokerProvider.class).request().rx(RxFlowableInvoker.class).get(Temperature.class).map(temperature -> new Forecast(temperature);我們注冊了額外的RxFlowableInvokerProvider ,它允許以后請求RxFlowableInvoker 。 此調用然后給了我們Flowable從RxJava返回類型。 這些類不在JAX-RS API中,我們必須將它們與Jersey RxJava2庫一起添加:
<dependency><groupId>org.glassfish.jersey.ext.rx</groupId><artifactId>jersey-rx-client-rxjava2</artifactId><version>2.26</version> </dependency>乍一看,似乎我們在做同一件事的同時使代碼變得更加復雜。 但是, Flowable實例使我們能夠輕松組合多個調用:
Flowable.concat(flowable1, flowable2).doOnNext(forecast -> {forecasts.add(forecast);}).doOnComplete(() -> {asyncResponse.resume(Response.ok(forecasts).build());}).doOnError(asyncResponse::resume).subscribe(); }對于從任何流通量收到的每個預測,我們將其添加到預測列表中。 最后,我們將預測列表作為響應發送或發送錯誤響應。 要注冊偵聽器,必須最終調用subscribe() ,否則它們將被忽略。
您可能還注意到asyncResponse變量用于發送最終響應或發出錯誤信號。 這是一個JAX-RS異步響應實例,用于在數據可用時在以后的時間完成REST響應,而不會阻塞初始處理線程。 使用異步響應有助于在等待外部REST服務的結果時節省線程資源。 為了在REST端點中打開異步處理,我們將注入javax.ws.rs.container.AsyncResponse作為REST方法參數,以及@Suspended批注。 我們還將返回類型更改為void,因為我們將使用AsyncResponse實例構建響應:
@GET @Produces(MediaType.APPLICATION_JSON) public void getForecasts(@Suspended AsyncResponse asyncResponse) {...here come some asynchronous calls to REST services...asyncResponse.resume(...) }最終代碼示例
以下代碼將:
- 在getForecasts方法中打開REST請求的異步處理
- 在異步響應上設置5分鐘超時
- 對倫敦和北京執行兩次溫度服務,而無需等待結果
- 將結果合并為一系列預測
- 將序列中的每個預測添加到列表中
- 處理完所有結果后發送完整列表
- 發生異常時發送錯誤結果
- 使用subscribe方法注冊處理程序
翻譯自: https://www.javacodegeeks.com/2018/06/speed-services-reactive-api.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的使用Java EE 8中的反应式API加速服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笔记本电脑capslk(笔记本电脑cap
- 下一篇: 佳能r38如何连接电脑(佳能2530i怎