成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文讀懂響應式編程到底是什么?

開發 前端
為了應對高并發服務器端開發場景,在2009 年,微軟提出了一個更優雅地實現異步編程的方式—— Reactive Programming ,我們稱之為響應式編程。

 最近幾年,隨著Go、Node 等新語言、新技術的出現,Java 作為服務器端開發語言老大的地位受到了不小的挑戰。雖然Java 的市場地位在短時間內并不會發生改變,但Java 社區還是將挑戰視為機遇,并努力、不斷地提高自身應對高并發服務器端開發場景的能力。

為了應對高并發服務器端開發場景,在2009 年,微軟提出了一個更優雅地實現異步編程的方式—— Reactive Programming ,我們稱之為響應式編程。

隨后,各語言很快跟進,都擁有了屬于自己的響應式編程實現。比如,JavaScript 語言就在ES6 中通過Promise 機制引入了類似的異步編程方式。同時,Java 社區也在快速發展,Netflix 和LightBend 公司提供了RxJava 和Akka Stream 等技術,使得Java 平臺也有了能夠實現響應式編程的框架。

當下,我們通過Mina 和Netty 這樣的NIO 框架其實就能完成高并發下的服務器端開發任務,但這樣的技術只掌握在少數高級開發人員手中,因為它們難度較大,并不適合大部分普通開發者。

雖然目前已經有不少公司在實踐響應式編程,但整體來說,其應用范圍依舊不大。出現這種情況的原因在于當下缺少簡單、易用的技術,這些技術需要能使響應式編程更加普及,并做到如同Spring MVC 一樣結合Spring 提供的服務對各種技術進行整合。

在2017 年9 月28 日,Spring 5 正式發布。Spring 5 發布最大的意義在于,它將響應式編程技術的普及向前推進了一大步。而同時,作為在背后支持Spring 5 響應式編程的框架Spring Reactor,也進入了里程碑式的3.1.0 版本。

響應式編程到底是什么?

在現實生活中,當我們聽到有人喊我們名字的時候,會對其進行響應,也就是說,我們是基于事件驅動模式來進行編程的。所以這個過程其實就是下發產生的事件,然后我們作為消費者對下發事件進行一系列的消費。

從這個角度來說,對整個代碼的設計應該是針對消費者來進行的。比如,看電影,有些畫面我們不想看,那就閉上眼睛;有些聲音不想聽,那就捂上耳朵。其實這就是對消費者的增強包裝,我們把復雜的邏輯拆分開,然后將其分割成一個個小任務進行封裝,于是就有了諸如filter、map、skip、limit 等操作。

01

并發與并行的關系

可以說,并發很好地利用了CPU 時間片的特性,也就是操作系統選擇并運行一個任務,接著在下一個時間片內運行另一個任務,并把前一個任務設置成等待狀態。其實并發并不意味著并行。

具體列舉下面幾種情況。

① 有時候,多線程執行會提高應用程序的性能,而有時候反而會降低應用程序的性能。這在 JDK 中Stream API 的使用上體現得很明顯,如果任務量很小,而我們又使用了并行流,反而降低了應用程序的性能。

② 在多線程編程中,可能會同時開啟或者關閉多個線程,這樣會產生很大的性能開銷, 也降低了應用程序的性能。

③ 當線程同時處于等待I/O 的過程中時,并發可能會阻塞CPU 資源,其后果不僅是用戶長時間等待,而且會浪費CPU 的計算資源。

④ 如果幾個線程共享了一個數據,情況就會變得有些復雜。我們需要考慮數據在各個線程中的狀態是否一致。為了達到數據一致的目的,很可能會使用synchronized 或者lock 相關操作。

現在,你對并發有一定的了解了吧。并發很好,但并不一定會實現并行。并行是在多核CPU 上同一時間運行多個任務或者一個任務分為多塊同時執行(如ForkJoin)。單核CPU 的話,就不要考慮并行了。

補充一點,實際上多線程就意味著并發,但是并行只發生在這些線程在同一時間調度、分配到不同CPU 上執行的情況下。也就是說,并行是并發的一種特定形式。一個任務里往往會產生很多元素,這些元素在不參與操作的情況下大都只能處于當前線程中,這時我們可以對其進行ForkJoin,但這對很多程序員來講有時候很不好操作、控制,上手難度有些大。這時如果用響應式編程,就可以簡單地通過所提供的調度API 輕松做到事件元素的下發、分配,其內部會將每個元素包裝成一個任務并提交到線程池中,我們可以根據任務是計算型的還是I/O 型的來選擇相應的線程池。

在這里,需要強調一下,線程只是一個對象,不要把它想象成CPU 中的某一個執行核心,這是很多人都在犯的錯,CPU 時間片會切換執行這些線程。

02

如何理解響應式編程中的背壓

背壓,由Back Pressure 翻譯得到,從英文字面意思講,稱之為回壓可能更合適。首先解釋一下回壓,它就好比用吸管喝飲料,將吸管內的氣體吸掉,吸管內形成低壓,進而形成飲料至吸管方向的吸力,此吸力將飲料吸進人嘴里。我們常說人往高處走,水往低處流,水之所以會出現這種現象,其實是重力所致。而現在吸管下方的水上升進入人的口中,說明出現了下游指向上游的逆向壓力,而且這個逆向壓力大于重力,可以稱這種情況為背壓。這是一個很直觀的詞,向后的、往回的壓力——Back Pressure。

放在程序中,也就是在數據流從上游源生產者向下游消費者傳輸的過程中,若上游源生產速度大于下游消費者消費速度,那么可以將下游想象成一個容器,它處理不了這些數據,然后數據就會從容器中溢出,也就出現了類似于吸管例子中的情況?,F在,我們要做的事情就是為這個場景提供解決方案,該解決方案被稱為背壓機制。

為了更好地解決背壓帶來的問題,我們回到現實中看一個事物——大壩。在發洪水期間,下游沒辦法一下子消耗那么多水,大壩此時的作用就是攔截洪水,并根據下游的消耗情況酌情排放,也就是說,背壓機制應該放在連接元素生產者和消費者的地方,即它是生產者和消費者的銜接者。然后,根據上面對大壩的描述,背壓機制應該具有承載元素的能力,也就是它必須是一個容器,而且其存儲與下發的元素應該有先后順序,那么這里使用隊列是最適合的了。背壓機制僅起承載作用是不夠的,正因為上游進行了承壓,所以下游可以按需請求元素,也可以在中間根據實際情況進行限流,以此上下游共同實現了背壓機制。在本書后續內容及相關的配套視頻中會介紹背壓的相關API。

03

Reactor 與RxJava 的對比

關于響應式編程,我寫的《Java 編程方法論:響應式RxJava 與代碼設計實戰》一書已經出版,那么Reactor 與RxJava 又有什么區別呢?首先我要明確地告訴你,如果你使用的是Java 8+,那么推薦使用Reactor 3,而如果你使用的還是Java 6+或函數需要做異常檢查,那么推薦使用RxJava 2。

從上圖可以看到,RxJava 2 和Reactor 共用了一套接口API 標準Reactive Streams Commons,這也說明它們的最終目的是一致的,而且API 具有通用性,這樣也降低了學習成本。

下面再來回顧一下RxJava。

迄今為止,RxJava 發行版主要分三大版本RxJava 3、RxJava 2 和RxJava 1。與RxJava 1 不同,RxJava 3、RxJava 2 直接通過新添加的Flowable 類型來實現Publisher 的接口定義(RxJava 3 與RxJava 2 并沒有太多區別,故這里只介紹RxJava 2)。同時,RxJava 2 依然保留了RxJava 1 中的Observable、Completable 和Single,并引入了支持Optional 的Single 升級版——Maybe 類型。RxJava 1 中的Observable 不支持RxJava 2 中的背壓機制,背壓機制是Flowable 的專有功能,不過Observable 內部提供了可轉換API。需要注意的是,Observable 實現的是RxJava 2 中自定義的ObservableSource 接口。

在Reactor 中,可以發現Mono 和Flux 兩種類型都實現了Publisher 接口,同時兩者皆實現了背壓機制。Flux 可以對標RxJava 2 中的Flowable 類型,而Mono 可以被理解為RxJava 2 中對Single 的背壓加強版。后續,我們會進行更深入的講解。

同樣,下面再來了解一下Reactor 與RxJava 的不同之處。

  • 為了兼容 Java 1.6+ ,RxJava 不得不自行定義了一些函數式接口,可以參考io.reactivex.functions 下的接口定義。而Reactor 3 則是基于JDK 中提供的java.util.function 來設計實現的。
  • 可以很輕松地從java.util.stream.Stream 轉換為Flux,也可以很輕松地由后者轉換為前者。
  • 同樣,可以很輕松地實現CompletableFuture 與Mono 之間的互相轉換,也可以輕松而安全地基于Optional 類型的元素創建Mono。
  • Reactor 3 可以更好地服務于Spring Framework 5,也更適應最新版本的JDK。

最后,我們再簡單介紹一下上圖中的幾個部分。

Core 是我們主要研究的庫,是Reactor 的核心實現庫。其作用與RxJava 2 的核心實現的作用是一樣的,本書主要介紹reactor-core 模塊。

IPC 可以認為它是針對encode、decode、send(unicast、multicast 或request/response )及服務連接而設計的支持背壓的組件。IPC 支持Kafka、Netty 及Aeron。

Addons 其中包括reactor-adapter、reactor-logback 和reactor-extra。reactor-adapter 可以說是連接RxJava 1/2 中Observable、Completable、Flowable、Single、Maybe、Scheduler 的橋梁,可以方便地與Reactor 3 進行轉換操作。同樣,這個庫對于Swing/SWT Scheduler、Akka Scheduler 也做了針對性適配。reactor-logback 用于支持Reactor Core 異步處理Logback 方面的功能。reactor-extra 為數字類型的Flux 源提供了很多數學運算的操作。

Reactive Streams Commons 是RxJava 2 和Reactor 共用的一套接口API 標準。

責任編輯:張燕妮 來源: 今日頭條
相關推薦

2021-01-18 13:05:52

Serverless Serverfull FaaS

2022-07-15 08:16:56

Stream函數式編程

2019-12-04 13:50:07

CookieSessionToken

2023-06-26 16:51:49

數字孿生數字技術

2025-05-06 08:35:00

2016-10-25 14:35:05

分布式系統 存儲

2023-09-18 07:23:25

ESQS散片

2021-10-18 14:30:55

物聯網IOT

2023-12-22 19:59:15

2021-08-04 16:06:45

DataOps智領云

2023-05-11 15:24:12

2019-09-04 19:29:14

云計算混合云資源

2019-06-28 08:31:01

微內核安卓系統

2011-04-27 09:30:48

企業架構

2020-09-27 06:53:57

MavenCDNwrapper

2020-09-22 08:22:28

快充

2020-10-14 06:22:14

UWB技術感知

2010-11-01 01:25:36

Windows NT

2018-05-29 16:20:55

區塊鏈比特幣

2018-09-28 14:06:25

前端緩存后端
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一区二区三区四区五区午夜 | 91资源在线 | 久久久精彩视频 | 精品乱子伦一区二区三区 | 91免费视频观看 | 亚洲精品一区二三区不卡 | 欧美在线一区二区三区四区 | 国产成人精品一区二区三区在线 | 久久国内 | 欧美国产精品 | 国产成人久久久 | 99久久99久久精品国产片果冰 | 亚洲国产中文字幕 | 国产精品成av人在线视午夜片 | 久久久夜夜夜 | 日本高清视频网站 | 天天干夜夜操 | 国产精品欧美一区二区 | 欧美一级大片免费观看 | 日韩在线国产 | 日韩在线视频观看 | 国产91综合一区在线观看 | 91在线免费视频 | 亚洲区一区二 | 欧美黄色录像 | 国产精品自拍视频 | 九一在线| 99久久久久久 | a毛片| 国产欧美日韩在线观看 | 日韩一区三区 | 天天视频一区二区三区 | 久久久久免费观看 | 中文字幕在线网 | 一区二区三区四区不卡视频 | 国产精品一区在线观看 | 91精品国产综合久久久动漫日韩 | 精品一区在线 | 国产精品久久久久久妇女 | 伊人性伊人情综合网 | 天堂色网 |