自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Spring WebFlux 要革了誰(shuí)的命?

開(kāi)發(fā) 開(kāi)發(fā)工具
國(guó)王看到這個(gè)新的Spring WebFlux簡(jiǎn)直是要革了好幾個(gè)大員的命,也只好安撫一下Tomcat, Servlet:“這樣吧,新事物總得有個(gè)漸進(jìn)的采納過(guò)程,我們讓Spring MVC和Spring WebFlux 并存一段時(shí)間,讓臣民們按照自己的實(shí)際情況來(lái)選擇吧!”

 托夢(mèng)

Java國(guó)王昨晚做了一個(gè)夢(mèng)。

夢(mèng)中有個(gè)白胡子老頭兒,頗有仙風(fēng)道骨, 告訴他說(shuō):“你們Java啊,實(shí)在是太弱了,連一個(gè)基本的功能都實(shí)現(xiàn)不了!”

國(guó)王大為驚奇:“什么功能是我堂堂大Java搞不定的?”

老頭兒展示了兩行代碼:

  1. float salary = 1000; 
  2. float tax =  salary * 0.1; 

國(guó)王說(shuō):“這不很正常嗎,薪水(salary)是1000, 稅(tax)等于100,我國(guó)小學(xué)生都能算出來(lái)。”

老頭兒說(shuō):“我要是現(xiàn)在讓salary=2000,那tax等于多少啊?”

“還是100! 因?yàn)閠ax沒(méi)有被重新計(jì)算!”

“薪水變了,為什么稅不變呢? ”

“這個(gè)......”

看到國(guó)王不說(shuō)話了,老頭兒繼續(xù)說(shuō):“你們得建立變量tax和變量salary之間的關(guān)聯(lián),讓他們像Excel一樣,一個(gè)單元格的值變了,Excel的公式自然會(huì)更新另外一個(gè)單元格,讓它隨之變化。”

  1. float salary = 1000; 
  2. //假設(shè)這個(gè)命令建立了tax和salary之間的關(guān)聯(lián) 
  3. float tax <=  salary *0.1 
  4. salary = 2000 ; 
  5. assertEquals(200,tax);  //現(xiàn)在tax自動(dòng)變成了200 

國(guó)王說(shuō)道:“你這么做有什么用啊,再說(shuō)這也不是Java的問(wèn)題,所有的語(yǔ)言都有這個(gè)問(wèn)題啊......”

仙風(fēng)道骨的老頭兒沒(méi)有回答, 慢慢消失了。

發(fā)布-訂閱模式

第二天早朝,國(guó)王給大臣們講了自己這個(gè)奇怪的夢(mèng),看看誰(shuí)能幫自己解一解, 沒(méi)想到大臣們七嘴八舌,說(shuō)自己也做了同樣的夢(mèng)。

這就奇怪了,難道有神靈故意給大家托夢(mèng)嗎? 在夢(mèng)中,仙人老頭兒給大家舉的例子都是一模一樣的。

集合大臣小心翼翼地說(shuō)道:“難道他是在暗示我國(guó)的稅收太高了嗎, 有10%,要降低一點(diǎn)?”

國(guó)王瞪了他一眼:“胡說(shuō)些什么?我們的稅一點(diǎn)都不高,起征點(diǎn)提高到了5000,除了五險(xiǎn)一金扣除,我們還有房貸減免,租房減免,獨(dú)生子女減免,贍養(yǎng)老人減免等一系列政策, 怎么能叫高呢?”

集合大臣趕緊噤聲。

IO大臣繼續(xù)說(shuō):“陛下不用煩惱,老頭兒說(shuō)的問(wèn)題,我們Java早已經(jīng)提供了對(duì)應(yīng)的解決方案,那就是發(fā)布者-訂閱者模式啊。如果把Salary當(dāng)成一個(gè)數(shù)據(jù)源的發(fā)布者, 把Tax當(dāng)成一個(gè)訂閱者,注冊(cè)到Salary當(dāng)中, 每當(dāng)Salary有變化,就發(fā)送一個(gè)事件給Tax,Tax收到后,做相應(yīng)的計(jì)算就可以了。”

 

 

[[258600]]

 

“這不就是一種把數(shù)據(jù)持續(xù)推送給觀察者或者訂閱者的一種模式嘛,這種小兒科的東西,有什么用?” 老對(duì)頭線程大臣說(shuō)道。

“在這個(gè)場(chǎng)景下確實(shí)沒(méi)啥用處,但是這種事件流的方式,如果處理好了,也許能解決大問(wèn)題。” IO大臣雖然不太服氣,但是也想不出什么好的應(yīng)用場(chǎng)景出來(lái)。

高并發(fā)

國(guó)王看到兩個(gè)老家伙又要干起來(lái),馬上轉(zhuǎn)移話題:“聽(tīng)說(shuō)我們Java在高并發(fā)方面遇到了一點(diǎn)兒?jiǎn)栴}?”

IO大臣立刻興奮起來(lái),順桿就爬:“沒(méi)錯(cuò),這二十來(lái)年,我們Java一直使用Tomcat那種線程池的方式,現(xiàn)在在越來(lái)越差勁了,難以應(yīng)對(duì)高并發(fā)了。”

這一下子把Tomcat大臣,線程大臣,甚至Servlet大臣都給拉了進(jìn)來(lái),國(guó)王暗自后悔。

IO大臣繼續(xù)侃侃而談:“現(xiàn)在的模型每來(lái)一個(gè)請(qǐng)求都會(huì)有一個(gè)線程來(lái)處理,如果這個(gè)請(qǐng)求涉及到IO或者網(wǎng)絡(luò)操作,這個(gè)線程不得不阻塞等待,沒(méi)法干別的事情。”

[[258600]]

 

“如果用戶的請(qǐng)求太多,那線程池中的線程很快就會(huì)被用光。這時(shí)候就沒(méi)辦法對(duì)外提供服務(wù)了。”

[[258600]]

 

這確實(shí)是實(shí)情,基于Servlet的線程模型,就是這么工作的。

國(guó)王問(wèn)道:“那個(gè)線程調(diào)用RPC服務(wù)的時(shí)候,為什么要等待呢? 讓它去干別的事情,比如處理另外一個(gè)請(qǐng)求不就可以了?”

“陛下圣明,這就是關(guān)鍵所在,要充分地利用線程,一點(diǎn)出現(xiàn)IO調(diào)用,立刻走開(kāi),去干別的事情,等到IO調(diào)用結(jié)束了,就可以通知線程去處理,這樣我們用少量的線程,就可以實(shí)現(xiàn)大量的并發(fā)了。”

國(guó)王說(shuō):“愛(ài)卿言之有理,你已經(jīng)可以實(shí)現(xiàn)這種NIO的方式了,對(duì)吧?”

“沒(méi)錯(cuò),現(xiàn)在我們要做的就是要改造Tomcat,改造甚至替換Servlet !”

回調(diào)地獄

Servlet大臣一聽(tīng)就急了,自己就是傳統(tǒng)的工作方式,一個(gè)請(qǐng)求一個(gè)線程,要是這么搞,自己位置不保,他把目光投向了忠實(shí)的盟友線程大臣。

線程大臣心領(lǐng)神會(huì):“IO大臣的辦法其實(shí)就是把同步的阻塞調(diào)用改成異步的非阻塞調(diào)用,不是那么容易啊,別的不說(shuō),這異步編程,對(duì)我們臣民來(lái)說(shuō)就很不容易。”

“你不是有什么Future,Callable之類(lèi)的東西嗎? 可以讓臣民們?nèi)ビ冒?” IO大臣不依不饒。

線程大臣笑了:“你是只知其一,不知其二,當(dāng)你調(diào)用那個(gè)future.get()的時(shí)候,如果線程的工作(例如數(shù)據(jù)庫(kù)查詢)還沒(méi)有做完,當(dāng)前線程還得等待,還是阻塞的。”

IO大臣有點(diǎn)兒后悔,自己怎么忽略了這一層呢?

線程大臣趁勝追擊:“還有啊,即使是按你所說(shuō),所有的操作都是異步的,都是事件驅(qū)動(dòng)的,那回調(diào)會(huì)大量存在,這代碼中回調(diào)地獄問(wèn)題,你考慮了嗎?”

  1. fun1(param,new Callback(){ 
  2.     void onSuccess(...){ 
  3.         ......執(zhí)行業(yè)務(wù)邏輯...... 
  4.         fun2(param,new Callback(){   
  5.             void onSuccess(...){ 
  6.                 ......執(zhí)行業(yè)務(wù)邏輯...... 
  7.                 fun3(param,new Callback(){ 
  8.                     void onSuccess(...){ 
  9.                         ......執(zhí)行業(yè)務(wù)邏輯...... 
  10.                         fun4(param,new Callback(){ 
  11.                             void onSuccess(...){ 
  12.                                 ......執(zhí)行業(yè)務(wù)邏輯......                               
  13.                             } 
  14.                             void onError(...){ 
  15.                             } 
  16.                         }); 
  17.                     } 
  18.                     void onError(...){ 
  19.                     } 
  20.                 }); 
  21.             } 
  22.             void onError(...){ 
  23.             } 
  24.         }); 
  25.     } 
  26.     void onError(...){ 
  27.     } 
  28. }); 

IO大臣看到這如同亂麻般的代碼,頭嗡的一聲就大了,這異步操作居然這么變態(tài)!

國(guó)王看到IO大臣神色有異,不再說(shuō)話,趕緊宣布退朝。

事件流

在朝堂上很郁悶的IO大臣怒氣沖沖地回到了家,下人送上的茶水也被他打翻在地。

幕僚已經(jīng)了解今日朝堂發(fā)生之事,走上前來(lái):“大人息怒,小人聽(tīng)說(shuō)民間有個(gè)叫做Reactor的東西,用什么事件流和函數(shù)式編程中的高階函數(shù),就能解決這個(gè)回調(diào)地獄問(wèn)題。”

事件流? IO大臣突然被點(diǎn)醒了,我怎么沒(méi)想起這茬兒, 昨天仙人托夢(mèng)不就是引導(dǎo)我用事件流嗎?

他趕緊問(wèn)道:“具體是怎么做的?”

“我們用圖來(lái)表示,一個(gè)事件流是這樣的, 在這個(gè)時(shí)間線上,還有Error事件和Complete事件,分別用來(lái)表示出錯(cuò)和完成,我就不畫(huà)了。”

[[258600]]

 

“了解,可是這又有什么用呢?” IO大臣問(wèn)道。

“可以使用函數(shù)式編程對(duì)這個(gè)事件流做變換,例如map,把事件從‘圓圈’ 變成了‘三角’”

 

 

[[258600]]

 

“還可以用filter對(duì)事件流做過(guò)濾”

[[258600]]

 

“嗯, 看起來(lái)很清楚,我想到一個(gè)場(chǎng)景, 先調(diào)用函數(shù)1,產(chǎn)生了事件流,然后對(duì)事件流中的每個(gè)元素,又要調(diào)用函數(shù)B,又產(chǎn)生了新的事件流,該怎么辦? ” IO大臣問(wèn)道。

“大人真是厲害,抽象思維能力極高! ” 幕僚適時(shí)地拍了一下馬屁,“這時(shí)候可以用flatmap,把新的事件流給平鋪了。”

 

 

[[258600]]

 

“map, filter, flatmap 僅僅是最基本的操作,還有switch , take, merge,zip等很多運(yùn)算符,你想要的功能都能滿足!”

“不錯(cuò),不錯(cuò),” IO大臣興奮地直搓手,他已經(jīng)把握住了其中的關(guān)鍵思想,回調(diào)地獄可以被解決了。

比如原來(lái)的需求是先異步調(diào)用fun1, 根據(jù)fun1的結(jié)果調(diào)用fun2, 只能這么寫(xiě):

  1. fun1(param,new Callback(){ 
  2.     void onSuccess(...){      
  3.         fun2(param,new Callback(){   
  4.             void onSuccess(...){ 
  5.                 ...... 
  6.             } 
  7.             void onError(...){ 
  8.             } 
  9.         }); 
  10.     } 
  11.     void onError(...){ 
  12.     } 
  13. }); 

現(xiàn)在假設(shè)fun1 返回的是數(shù)據(jù)流,fun2返回的也是數(shù)據(jù)流,用這種新的方式,可以寫(xiě)成這樣:

  1. fun1(param) 
  2. .flatMap( e -> func2(e)) 
  3. .subscribe(r -> showResult(r),  
  4.       error -> handleError(error)); 

相當(dāng)于把這一系列的回調(diào)給壓平了!

IO大臣問(wèn)道:“你剛才說(shuō)的民間的那個(gè)軟件叫什么來(lái)著? ”

“民間很多的,有RxJava, Reactor,要不要我把他們的負(fù)責(zé)人叫來(lái)聊聊?”

“慢著,光是這個(gè)Reactor, 用處不大,你把Spring大臣也請(qǐng)來(lái),我們需要讓Spring去使用Reactor,拋棄Servlet, 把所有的請(qǐng)求和處理都變成異步處理!”

新框架

三個(gè)月后,IO大臣喜氣洋洋地向國(guó)王匯報(bào):“陛下,臣已經(jīng)解開(kāi)了仙人所托的夢(mèng),那其實(shí)是讓我Java帝國(guó)實(shí)現(xiàn)反應(yīng)式編程(Reactive Programming)!”

“反應(yīng)式編程? 這名字有點(diǎn)古怪!”

“對(duì),這種方式是基于事件流和函數(shù)式編程的, 可以讓我們用非阻塞的、異步的方式來(lái)處理請(qǐng)求,還能解決回調(diào)地獄的問(wèn)題。”

IO大臣把Reactor給國(guó)王講了一遍。

“那這個(gè)Reactor該如何使用? ”

“陛下還記得我們Java的高并發(fā)問(wèn)題吧,就是由于沒(méi)法有效地管理異步和回調(diào)地獄導(dǎo)致的, 現(xiàn)在好了,臣和Spring攜手做了一個(gè)叫做Spring WebFlux的東西,獻(xiàn)給陛下,它不用Servlet,可以實(shí)現(xiàn)非阻塞的IO,可以有效地應(yīng)對(duì)高并發(fā)。 ” IO大臣展示了一幅圖。

 

 

[[258600]]

 

Servlet大臣一看,臉都綠了:我的位置在哪兒?

Tomcat大臣也覺(jué)得不爽,原來(lái)自己一家獨(dú)大,現(xiàn)在被Netty給擠走了。

只有JDBC大臣還不慌不忙:“用異步非阻塞處理所有東西? 你省省吧,我這里訪問(wèn)數(shù)據(jù)庫(kù)還是阻塞的呢!”

IO大臣心中暗叫不妙,怎么忘了JDBC這么重要的東西,既然想實(shí)現(xiàn)異步、非阻塞,那一定是端到端的,全鏈路的實(shí)現(xiàn),某個(gè)點(diǎn)的阻塞調(diào)用都會(huì)導(dǎo)致整體出問(wèn)題。

可他還是保持了鎮(zhèn)靜:“不用擔(dān)心,民間的開(kāi)源社區(qū)很快就會(huì)搞出來(lái)非阻塞的JDBC驅(qū)動(dòng)的。”

國(guó)王看到這個(gè)新的Spring WebFlux簡(jiǎn)直是要革了好幾個(gè)大員的命,也只好安撫一下Tomcat, Servlet:“這樣吧,新事物總得有個(gè)漸進(jìn)的采納過(guò)程,我們讓Spring MVC和Spring WebFlux 并存一段時(shí)間,讓臣民們按照自己的實(shí)際情況來(lái)選擇吧!”

 

后記:本文中托夢(mèng)中的例子來(lái)源于:http://blog.leapoahead.com/2016/03/02/introduction-to-reactive-programming/ 我做了改編。

【本文為51CTO專(zhuān)欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)作者微信公眾號(hào)coderising獲取授權(quán)】

 

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來(lái)源: 51CTO
相關(guān)推薦

2011-10-10 08:54:09

Siri蘋(píng)果語(yǔ)音識(shí)別

2013-01-18 09:25:48

微信移動(dòng)應(yīng)用YY

2023-09-26 07:22:20

2018-08-07 14:55:37

2013-08-20 09:49:43

2023-10-17 20:21:25

百度AI原生思維

2022-07-27 10:34:29

GoogleC++系統(tǒng)

2017-12-12 11:18:03

微信語(yǔ)音聊天

2020-09-09 12:53:14

AMDNVIDIACPU

2010-03-18 10:45:50

互聯(lián)網(wǎng)

2015-10-16 09:35:23

支付寶更新微信

2019-05-15 10:55:07

機(jī)器學(xué)習(xí)數(shù)據(jù)庫(kù)索引

2015-08-10 13:32:43

運(yùn)維公有云自動(dòng)化運(yùn)維

2016-07-25 14:31:04

辦公I(xiàn)T環(huán)境

2015-08-19 10:29:50

無(wú)線通信藍(lán)牙

2011-12-06 10:18:31

QQ通訊錄VOIP

2023-05-26 12:54:27

2019-04-29 14:37:11

虛擬化大數(shù)據(jù)服務(wù)器

2019-12-25 14:33:15

5G革命通信

2023-07-25 12:21:27

AI相機(jī)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)