1. 程式人生 > >【Scala】響應式程式設計思想

【Scala】響應式程式設計思想

何為響應式程式設計

響應式程式設計是一種面向資料流和變化傳播的程式設計正規化,資料更新是相關聯的。 這意味著可以在程式語言中很方便地表達靜態或動態的資料流,而相關的計算模型會自動將變化的值通過資料流進行傳播。
以響應式程式設計方式進行思考,意味著要放棄命令式且帶狀態的程式設計習慣,並且強迫你的大腦以一種不同的方式去工作。
響應式程式設計提高了程式碼的抽象層級,所以你可以只關注定義了業務邏輯的那些相互依賴的事件,而非糾纏於大量的實現細節。它可以簡化專案,特別是處理巢狀回撥的非同步事件、複雜的列表過濾和變換,或時間相關問題。

互動式程式設計與響應式程式設計

平時我們使用最多的便是“互動式(Interactive)”的程式設計方式,採用的是元件之間的相互呼叫來表現邏輯。例如,物件A向物件B請求資料並等待返回,待物件B完成並返還資料之後A才繼續進行後面的操作。
響應式程式設計是一種基於“改變”的程式設計方式。例如在互動式程式設計中,A = B + C這樣的表示式意味著將B與C之和賦給A,而此後B與C的改變都與A無關。而在響應式程式設計中,A會去“響應”B或C的變化,即一旦B或C改變之後,A的值也會隨之變化。響應式程式設計的一個典型應用便是GoF23中的觀察者模式。

響應式系統模型

Actor模型

Actor模型=資料+行為+訊息。Actor模型內部的狀態由自己的行為維護,外部執行緒不能直接呼叫物件的行為,必須通過訊息才能激發行為,這樣就保證Actor內部資料只有被自己修改。
Actor是一個個獨立的實體,他們之間是毫無關聯的。但是,他們可以通過訊息來通訊。一個Actor收到其他Actor的資訊後,它可以根據需要作出各種相應。Actor的常見應用模式是處理大規模併發輸入流:將具體工作分類給非同步的工作節點,之後返回工作節點計算的結果。
Actor模型實際上並不是純正的函數語言程式設計模型。Receive方法返回Unit型別,這意味著在該方法中,所有事情都是通過副作用完成的。再者,只要需要,Actor模型便會允許使用可變狀態,但這裡要遵守一個規則,將狀態封裝在某個actor中,並確保所有狀態的響應操作是執行緒安全的。
綜上,Actor模型是處理大規模、高度可用、事件驅動應用程式的更為通用的方法。

函式響應式程式設計(functional reactive programming,FRP)

在函式響應式程式設計模型中,基於時間的狀態需要通過某一系統傳播到需要使用這些狀態的程式碼中。當FRP模型中的某一狀態發生變化時,你並不需要手動地對依賴這些變化的變數進行更新,與之相反,FRP會使用宣告的方式描述資料元素之間的依賴關係,而FRP執行時則會負責狀態的傳播。因此,使用者使用函式式宣告語句和組合語法編寫程式碼。

FRP基本上就是面向非同步事件流的程式設計了,這個非同步事件流(Stream)是一個按時間排序的事件序列。Stream是不可變的,任何操作都返回新的Stream,且它是一個Monad。

響應式擴充套件(reactive extensions,Rx)

Reactive Extension 這個概念最早出現在.net社群的Rx.net,一個提供處理非同步事件的程式庫,其核心概念是Observable,表示有限或者無限多個現在或者將來到達的事件。Observable提供了onNext,onError,onCompleted供開發者定製新元素到達,出現錯誤,或者流結束時的程式的行為。並提供了List上類似的操作,如map,filter,reduce,大大降低了非同步事件程式設計的複雜度。
因為這些概念是如此的強大,以至於很多程式語言,如java,ruby,javascript很快就有了各自的reactvie extension。

Rx模型中的可觀察序列代表事件流或其他資料來源。通過將可觀察序列與LINQ(language-integrated query,語言整合查詢)庫提供的查詢操作符(組合器)拼接起來,Rx組成了非同步程式。

小結

Actor、FRP以及Rx都是基於事件的系統模型。FRP和Rx模型更像是一個處理各類事件流的管道系統,而Actor模型則像是一個包裝各個元件進行互動的網路系統。儘管略有差異,但是這些模型都能夠通過多種方式進行擴充套件。有一點可以斷言,Actor模型健壯的錯誤處理策略,使得它對響應性提供的支援稱為最強的支援。值得一提的是,儘管這些模型提高系統響應度的方式不同,但所有模型都致力於最大程度地減少阻塞。

響應式系統須遵循的特徵

所有可伸縮、可恢復的響應式程式都應遵循這些特徵。

訊息傳遞或事件傳遞

響應式系統必須能對訊息或事件進行響應,這是最基本的要求。

可靈活伸縮

為了能夠滿足處理要求,響應式系統是可伸縮的系統。這意味著該系統能夠通過水平擴充套件的方式進行擴容、調整程序數、處理核數、處理節點數。理想狀態下,為了能夠動態響應不停變化的處理需求,系統應該根據當前需求動態的執行水平擴充套件,這種調整既包括增加處理資源,也包括自動回收資源。用這種方法,我們需要花費大量的精力才能對那些需要維護重要狀態資訊的服務進行橫向擴充套件,而且這類系統也很難對狀態資訊進行“分片”和可靠的複製。

容錯可恢復

隨著系統不斷變大,那些不常見的事件也會越來越頻繁地出現在系統中。因此,錯誤也是需要考慮的頭等大事。構造響應式系統時,必須不斷進行改造,以便能夠在出現錯誤時優雅地恢復系統。所以常常需要弱耦合和通用的監督系統的設計。

響應式

響應式系統需要能夠隨時對服務請求進行響應,即使系統出現了錯誤的元件或是精力了非常高的流量峰值,響應式也需要通過優雅降級的方式繼續響應使用者的請求。

總結

本節中給出了響應式程式設計的基本概念,討論了響應式系統模型和所遵循的特徵。由於該方面的相關資料較為混亂,使得我在學習過程中難以把握一些概念的定界,待日後勤加實踐,從Scala的併發系統和akka框架入手,加深對響應式程式設計的理解。