《Java編程方法論:響應式RxJava與代碼設計實戰》序

原文連接: 《Java編程方法論:響應式RxJava與代碼設計實戰》序,來自於微信公衆號: 次靈均閣

正文內容

在《2019 一月的InfoQ 架構和設計趨勢報告》1中,響應式編程(Reactive Programming)和函數式(Functional Programing)仍舊編列在第一季度(Q1)的 Early Adopters(早期採納者) 中。儘管這僅是一家之言,然而很多的開發人員逐漸意識到 Reactive 之風儼然吹起。也許您的生產系統還沒有出現 Reactive 的身影,不過您可能據說過 Spring WebFlux 或 Netflix Hystrix 等開源框架。筆者曾請教過 Pivotal(Spring 母公司)佈道師 Josh Long2:」Spring 技術棧將來的重心是否要佈局在 Reactive 之上?「。對方的答覆是:」沒錯,Reactive 是將來趨勢。「。同時,愈來愈多的開源項目開始簽署 Reactive 宣言(The Reactive Manifesto)3,並喊出 」Web Are Reactive「 的口號。html

或許開源界的種種舉動沒法說服您向 Reactive 的」港灣「中停靠,不過 Java 9 Flow API4 的引入,又給業界注入了一劑強心針。不難看出,不管是 Java API,仍是 Java 框架均走向了 Reactive 編程模型的道路,這並不是是一種巧合。java

一般,人們談到的 Reactive 可與 Reactive 編程劃上等號,以」非阻塞(Non-Blocking)「和」異步(Asynchronous)「的特性並述,數據結構與操做相輔相成。Reactive 涉及函數式和併發兩種編程模型,前者關注語法特性,後者強調執行效率。簡言之,Reactive 編程的意圖在於 」Less Code,More Efficient「。除此以外,我的認爲 Reactive 更大的價值在於統一 Java 併發編程模型,使得同步和異步的實現代碼無異,同時作到 Java 編程風格與其餘編程語言更好地融合,或許您也發現 Java 與 JS 在 Reactive 方面並不存在本質區別。縱觀 Java 在 Reactive 編程上的發展而看,其特性更新可謂是步步爲營,如履薄冰。儘管 Java 線程 API ThreadRunnable 就已具有異步以及非阻塞的能力,然而同步和異步編程的模式並不統一,而且理解 Thread API 的細節和管理線程生命週期的成本均由開發人員歸納承受。雖然 Java 5 引入 J.U.C 框架(Java 併發框架)以後, ExecutorService 實現減輕了以上負擔。不過開發人員仍需關注 ExecutorService 實現細節,好比怎樣合理地設置線程池空間以及阻塞隊列又成爲新的挑戰。爲此,Java 7 又引入 ForkJoinPool API,不過此時的J.U.C 框架與 Reactive 理念仍存在距離,即便是線程安全的數據結構,也並不具有並行計算的能力,如:集合並行排序,同時操做集合的手段也至關的貧瘠,缺乏相似 Map/Reduce 等操做。不過這些困難只是暫時的,終究被 Java 8 」救贖「。Stream API 的出現不但具有數據操做在串行和並行間自由切換的能力,如 sequential() 以及 parallel() 方法,並且淡化了併發的特性,如 sorted() 方法便可能是傳統排序,亦或是並行排序。相同的設計哲學也體如今 Java Reactive 實現框架中,如同書中說起的 RxJava5 API io.reactivex.Observable 。統一編程模型只是 Stream 其中設計目標之一,它結合 Lambda 語法特性,雖然提供了數量可觀的操做方法,如 flatMap() 等,然而不管對比 RxJava,仍是 Reactor6Stream 操做方法卻又相形見絀。值得一提的是,這些操做方法在 Reactive 的術語中稱之爲操做符(Operators)。固然框架內建的操做符的多與寡,並不是判斷其是否爲 Reactive 實現的依據。其中決定性因素在於數據必須來源於發佈方(生產者)的」推送(Push)「,而非消費端的」拉取(Pull)「。顯然,Stream 屬於消費端已就緒(Ready)的數據集合,並不存在其餘數據推送源。不過 JVM 語言早期的 Reactive 定義處於模糊地帶,如 RxJava API 屬於觀察者模式(Observer Pattern)7的擴展,而非迭代器(Iterator Pattern)模式8的實現。而 Reactor 的實現則擁抱 Reactive Streams 規範9 ,該規範消費端對於數據的操做是被動的處理,而非主動的索。換言之,數據的到達存在着不肯定性10。當推送的數據沒法獲得消費端及時效應時,Reactive 框架必須提供背壓(Backpressure)11實現,確保消費端擁有」拒絕的權利(cancel)」。在此理論基礎上,Reactive Streams 規範定義了一套抽象的 API,做爲 Java 9 java.util.concurrent.Flow API 的頂層設計。不過關於操做符的部分,該規範彷佛不太關心,這也是爲何 RxJava 和 Reactor 均稱自身爲 Reactive 擴展框架的緣由,同時二者在 API 級別提供多種調度器(Schedulers)12實現,適配不一樣併發場景提供。儘管 Reactive 定義在不一樣的陣營之間存在差別,援引本人在《Reactive-Programming-一種技術-各自表述》13文中的總結:react

Reactive Programming 做爲觀察者模式( Observer) 的延伸,不一樣於傳統的命令編程方式( Imperative programming)同步拉取數據的方式,如迭代器模式( Iterator) 。而是採用數據發佈者同步或異步地推送到數據流(Data Streams)的方案。當該數據流(Data Steams)訂閱者監聽到傳播變化時,當即做出響應動做。在實現層面上,Reactive Programming 可結合函數式編程簡化面嚮對象語言語法的臃腫性,屏蔽併發實現的複雜細節,提供數據流的有序操做,從而達到提高代碼的可讀性,以及減小 Bugs 出現的目的。同時,Reactive Programming 結合背壓(Backpressure)的技術解決發佈端生成數據的速率高於訂閱端消費的問題。

不難看出,Reactive 是一門綜合的編程藝術,在實現框架的加持下,相同的代碼邏輯實現同步和異步非阻塞功能,從而達到提高應用總體性能的目的。不過現實的狀況或許沒有那麼理想,Spring 官方文檔在《Web on Reactive Stack》章節中提到,"Reactive 和非阻塞一般並非讓應用運行的更快"14git

Reactive and non-blocking generally do not make applications run faster.

爲此,JHipster15 給出了一份《 Spring 5 WebFlux 性能測試報告》16,其中一條結論是,」Reactive 應用並無表現出速度提高(甚至是變得更差)「:github

No improvement in speed was observed with our reactive apps (the Gatling results are even slightly worse).

數月後,看似相反的結論卻在DZone17一篇名爲《Raw Performance Numbers - Spring Boot 2 Webflux vs. Spring Boot 1》18的文中出現,測試結果是 Spring Boot 2 WebFlux在高併發下響應時間更爲平穩。實際上,這個測試結論有些」關公戰秦瓊「的味道,畢竟 Spring Boot 2.0 下的 WebFlux 和 Spring Boot 1.0 中的 Servlet 容器所使用線程模型是不一樣的,而且 Servlet 3.0 異步以及非阻塞特性缺省是關閉的。不過以上兩篇的結論並不矛盾,前者關注於響應速度,後者則強調吞吐量,都是性能的核心指標。遺憾的是,兩篇文章均未對各自的測試用例作出調優,所以以上結論都存在必定的侷限性,這也是本人對 Reactive 技術可否提高性能提出質疑的地方。web

若是本人是國內提出 Reactive 問題的第一人的話,那麼知秋19就是國內第一個解決問題的人。做爲國內爲數很少的 Reactive 以及 NIO 方面的專家,在技術研究上,他追求格物致知,不輕忽技術細節。在知識分享上,他可謂是知無不言,言無不盡,不只在社交羣中答疑解惑,並且錄製免費視頻,發佈在 B 站20以及 YouTube 頻道21,並獲得 Josh Long 等大佬的推文(Twitter)。或許以上方式還不足以完整地討論 Java Reactive 技術,知秋選擇了漫長而又艱苦的著書之路,儘管他是本人的朋友,然而 」內舉不避親「,筆者推薦給讀者朋友,首先是由於這是大陸地區第一本全面解讀 Java Reactive 技術的書籍,除做者的雄厚技術積累背書以外,書中的知識脈絡是按部就班的。同時,這也是一本引人深思的書,本書在導讀源碼的同時,也引導讀者對於代碼設計上的思考。再者,這又是一本知識苦旅的書,由於它涉及面較廣,讀者不只須要具有必定的 Java 併發以及面向對象設計,並且須要讀者付出較多的時間去反覆推敲。正所謂」夫夷以近,則遊者衆;險以遠,則至者少「22,筆者但願讀者在購買此書後,不輕言放棄,當您面臨挑戰時,那纔是成長的開始。同時,也期盼讀者將 Reactive 技術付之於實踐,提前觸碰將來。spring

小馬哥(mercyblitz)23apache

2019 年 3 月 5 日編程

書籍推薦

-《Java編程⽅方法論:響應式RxJava與代碼設計實戰》
-《高可⽤可伸縮微服務架構:基於Dubbo、Spring Cloud和Service Mesh》
-《Spring Boot 編程思想(核⼼篇)》segmentfault

線上分享

免費分享

收費分享

深刻探討 Java 相關技術,包括行業動態,架構設計,設計模式,框架使用,源碼分析等。

參考資源


  1. Architecture and Design InfoQ Trends Report - January 2019 - https://www.infoq.com/article...
  2. Josh (@starbuxman) is the Spring Developer Advocate at Pivotal and a Java Champion - https://spring.io/team/jlong
  3. The Reactive Manifesto - https://www.reactivemanifesto...
  4. https://docs.oracle.com/javas...
  5. RxJava: Reactive Extensions for the JVM - https://github.com/ReactiveX/...
  6. Reactor is a fully non-blocking reactive programming foundation for the JVM, with efficient demand management (in the form of managing "backpressure"). - https://github.com/reactor/re...
  7. Observer Pattern - http://en.wikipedia.org/wiki/...
  8. Iterator Pattern - https://en.wikipedia.org/wiki...
  9. Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure. - https://www.reactive-streams....
  10. Handling streams of data—especially 「live」 data whose volume is not predetermined - https://github.com/reactive-s...
  11. Backpressure is an integral part of this model in order to allow the queues which mediate between threads to be bounded. The benefits of asynchronous processing would be negated if the backpressure signals were synchronous (see also the Reactive Manifesto), therefore care has been taken to mandate fully non-blocking and asynchronous behavior of all aspects of a Reactive Streams implementation. - https://github.com/reactive-s...
  12. RxJava Scheduler - http://reactivex.io/documenta... Reactor Schedulers : https://projectreactor.io/doc...
  13. 《Reactive Programming 一種技術,各自表述》:https://mercyblitz.github.io/...
  14. 1.1.6. Performance - https://docs.spring.io/spring...
  15. JHipster -https://www.jhipster.tech/
  16. 《Spring 5 WebFlux: Performance tests》- https://blog.ippon.tech/sprin...
  17. DZone : https://dzone.com
  18. 《Raw Performance Numbers - Spring Boot 2 Webflux vs. Spring Boot 1》 - https://dzone.com/articles/ra...
  19. 知秋,本書的做者筆名
  20. https://space.bilibili.com/24...
  21. https://www.youtube.com/chann...
  22. 《遊褒禪山記》,王安石
  23. 小馬哥,Java 勸退師Apache Dubbo PPMC、Spring Cloud Alibaba 項目架構師 - https://mercyblitz.github.io/...
相關文章
相關標籤/搜索