反應式編程響應式reactive基本概念

反應式編程 (reactive programming) 是一種基於數據流 (data stream) 和 變化傳遞 (propagation of change) 的聲明式 (declarative) 的編程範式。

反應式編程是在命令式編程、面向對象編程之後出現的一種新的編程模型,是一種以更優雅的方式,通過異步和數據流來構建事務關係的編程模型。本文包括反應式編程的概述和 RxPy 實戰,以及怎樣去理解反應式編程才能更好的把它融入到我們的編程工作中,把反應式編程變成我們手中的利器。

使用異步數據流進行編程,這意味着可以在編程語言中很方便地表達靜態或動態的數據流,而相關的計算模型會自動將變化的值通過數據流進行傳播。反應式編程提高了代碼的抽象級別,可以只關注定義了業務邏輯的那些相互依賴的事件。

反應式系統具有如圖所示的4個特性:

  1. 即時響應性,對用戶有反應: 對用戶有反應我們才說響應,一般我們說的響應,基本上都說得針對跟用戶來交互。只要有可能,系統就會及時響應。

  2. 回彈性,對失敗有反應: 應用失敗了系統不能無動於衷,不能等着它掛掉,要有反應,使其具備可恢復性。可恢復性可以通過複製、監控、隔離和委派等方式實現。在可恢復性的系統中,故障被包含在每個組件中,各組件之間相互隔離,從而允許系統的某些部分出故障並且在不連累整個系統的前提下進行恢復。當某個模塊出現問題時,需要將這個問題控制在一定範圍內,這便需要使用隔絕的技術,避免雪崩等類似問題的發生。或是將出現故障部分的任務委託給其他模塊。回彈性主要是系統對錯誤的容忍。

  3. 彈性,對容量和壓力變化有反應: 在不同的工作負載下,系統保持響應。系統可以根據輸入的工作負載,動態地增加或減少系統使用的資源。這意味着系統在設計上可以通過分片、複製等途徑來動態申請系統資源並進行負載均衡,從而去中心化,避免節點瓶頸。如果沒有狀態的話,就進行水平擴展,如果存在狀態,就使用分片技術,將數據分至不同的機器上。

     

  4. 消息驅動,對輸入有反應: 響應系統的輸入,也可以叫做消息驅動。反應式系統依賴異步消息傳遞機制,從而在組件之間建立邊界,這些邊界可以保證組件之間的鬆耦合、隔離性、位置透明性,還提供了以消息的形式把故障委派出去的手段。

     

前三種特性(即時響應性, 回彈性, 彈性)更多的是跟你的架構選型有關,我們可以很容易理解像 Microservices、Docker 和 K8s 這樣的技術對建立反應式系統的重要性。

回壓(Backpressure)

這裏要特別要提一下回壓(Backpressure), Backpressure 其實是一種現象,在數據流從上游生產者向下遊消費者傳輸的過程中,上游生產速度大於下游消費速度,導致下游的 Buffer 溢出,這種現象就叫做 Backpressure 出現。這句話的重點不在於”上游生產速度大於下游消費速度”,而在於”Buffer 溢出”。回壓和 Buffer 是一對相生共存的概念,只有設置了 Buffer,纔有回壓出現;只要設置了 Buffer,一定存在出現回壓的風險。

比如我們開發一個後端服務,有一個 Socket 不斷地接收來自用戶的請求來把用戶需要的數據返回給用戶。我們服務所能承受的同時訪問用戶數是有上限的,假設最多隻能承受 10000 的併發,再多的話服務器就有當掉的風險了。對於超過 10000 的用戶,程序會直接丟棄。那麼對於這個案例 10000 就是我們設置的 Buffer,當超過 10000 的請求產生時,就造成了回壓的產生;而我們程序的丟棄行爲,就是對於回壓的處理。

對於回壓我們一般有兩種處理方式,一種就是上面舉例中的拒絕或丟棄,這是否定應答的方式,另一種是肯定應答,先收下來,然後再慢慢處理。

 

 

 

Rx

反應式編程最着名的實現是 ReactiveX,其爲 Reactive Extensions 的縮寫,一般簡寫爲 Rx ,發展歷程如圖所示:

640?wx_fmt=png

微軟 2009 年 以 .Net 的一個響應式擴展的方式創造了Rx,其藉助可觀測的序列提供一種簡單的方式來創建異步的,基於事件驅動的程序。2012 年 Netflix 爲了應對不斷增長的業務需求開始將 .NET Rx 遷移到 JVM 上面。並於 2013 年 2 月份正式向外發佈了 RxJava 。

Rx的組成包括5部分,被觀察者或者叫發射源,觀察者/訂閱者或者叫接收源,訂閱,調度器,操作符。

  • Observable<Data> 被觀察者可以被觀察者訂閱,被觀察者將數據push給所有的訂閱者

  • Subscriber /Observer

  • Subscription 訂閱可以被取消訂閱

  • Schedulers 調度器是Rx的線程池,操作中執行的任務可以指定線程池,我們可以通過subscribeOn來指定Observable的任務在某線程池中執行Observable

  • 也可以通過observeOn來指定訂閱者/觀察者們,在哪個線程執行onNext, onComplete, onError
    Operators 操作符可以對數據流進行各種操作,包括創建,轉換,過濾,組裝,合併 ,篩選等等

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章