公司最近新項(xiàng)目選用了webFlux作為基礎(chǔ)架構(gòu),也在緩慢的學(xué)習(xí)中。只因奈何相關(guān)API文檔太少了,新版本的資料那就更少了,國內(nèi)很多教程都是老版本的,只能是摸著石頭過河。本系列的東西只是我個(gè)人鑒于文章之日的理解,肯定有不對(duì)的地方,如果您發(fā)現(xiàn)了,勞煩辛苦回復(fù)指出,先感謝。
程序員的危機(jī)
1.webflux完全拉低了程序員菜鳥和老鳥的差距,只要你用webflux寫代碼寫出來的代碼在性能上不會(huì)再有天壤之別了。目這是對(duì)傳統(tǒng)程序員的一種沖擊,工作年限可能真不是問題了。函數(shù)式流編程是未來!
2.傳統(tǒng)應(yīng)用架構(gòu)師常用 切面 ,反射 在這里不好使了,很多花樣都沒法玩,該職位未來會(huì)向著 云生架構(gòu)師的方向進(jìn)化,讓其在更宏觀的眼界來工作,從大廠最近的招聘上也能看出有這個(gè)趨勢了
3.在語法上,在使用flatmap這些流式api時(shí) 默認(rèn)會(huì)使用final修飾變量,基本變量的操作強(qiáng)制會(huì)讓你使用juc包下的atomic類型的,從編碼層面就限制你使用鎖機(jī)制,也就消除了死鎖的問題
4.傳統(tǒng)編碼中的內(nèi)存泄漏一直是個(gè)容易出現(xiàn)但是卻很難定位得問題,并且內(nèi)存泄漏一定是代碼問題,webflux設(shè)計(jì)上則規(guī)避了這些問題。它不需要你明確得new對(duì)象了。前提只要你規(guī)范使用它的api。
5.線程是java服務(wù)器的稀缺資源,所以就要使用線程池配合限流保證服務(wù)可用,線程池合理的參數(shù)配置是很有學(xué)問的,使用webflux不用在考慮 限流,線程池這些,webflux幫你搞定,
Wenflux存在的問題
1.自動(dòng)生成api文檔頁面,這個(gè)問題緊在route方式,spring自己提供了一個(gè)解決方案就是每個(gè)接口必須寫測試用例,但是不是很優(yōu)雅,目前還不知道有什么方式可以像使用swagger那樣編輯,也可能是我還沒接觸到吧
2.因?yàn)榉瓷浜蚢op的問題,多數(shù)據(jù)源的問題還沒有找到像傳統(tǒng)項(xiàng)目中那種優(yōu)雅的方式,后面的文章會(huì)放上找到的方式
3.流式編程代碼的調(diào)試變得復(fù)雜,我們不能一行一行的調(diào)試了,開發(fā)中把日志加全一些吧
webflux 是什么?
Spring 5新加入的響應(yīng)式流編程技術(shù)棧是其主打核心特性,最低Springbooot2.0,底層使用Netty,這個(gè)從搭建好項(xiàng)目啟動(dòng)日志中能看出來。
webflux的三個(gè)組件
1.Router Functions: 對(duì)標(biāo)@Controller,@RequestMapping等標(biāo)準(zhǔn)的Spring MVC注解,提供一套函數(shù)式風(fēng)格的API,用于創(chuàng)建Router,Handler和Filter。
2.WebFlux: 核心組件,協(xié)調(diào)上下游各個(gè)組件提供響應(yīng)式編程支持。
3.Reactive Streams: 一種支持背壓(Backpressure)的異步數(shù)據(jù)流處理標(biāo)準(zhǔn),主流實(shí)現(xiàn)有RxJava和Reactor,Spring WebFlux默認(rèn)集成的是Reactor,
值得一提的是,除了新的Router Functions接口,Spring WebFlux同時(shí)支持使用老的Spring MVC注解聲明Reactive Controller。和傳統(tǒng)的MVC Controller不同,Reactive Controller操作的是非阻塞的ServerHttpRequest和ServerHttpResponse,而不再是Spring MVC里的HttpServletRequest和HttpServletResponse
在路由方式的選擇上 建議使用webflux的router風(fēng)格,它比Reactive Controller的方式更符合函數(shù)編程的思想,在請求的鏈路上比Controller更快一些
下面的內(nèi)容,入學(xué)者多體會(huì)
流編程是jdk1.8的新特性,webflux是在其基礎(chǔ)思想上更高層的應(yīng)用,StreamAPI網(wǎng)上學(xué)學(xué)吧,教程太多了,這里用生活中的例子幫你理解,先理解思想
1.在webflux的世界中 一切都是流,一個(gè)請求過來到返回是一個(gè)完整的流,中間是不能斷的,執(zhí)行了中斷指令是就違背了webflux設(shè)計(jì)的本意
2.已南水北調(diào)為例,從南到北是一條線,國家已經(jīng)從地圖上畫好了線,從哪到哪都明確標(biāo)注了,施工時(shí)中間經(jīng)過的各個(gè)地區(qū)每隔一段修建一個(gè)蓄水池(webflux中就是我們具體的業(yè)務(wù)處理了),逐級(jí)接力把水送到北方,但是這條線是不能改的,在webflux的設(shè)計(jì)中也是這樣,千萬千萬不要讓流中斷
3. 國家在有南水北調(diào)這個(gè)想法時(shí)想把它實(shí)現(xiàn),想象一下如果你是領(lǐng)導(dǎo)是不是 先設(shè)定方案、實(shí)地考察中途經(jīng)過的地區(qū)、確定方案路線、組織各級(jí)政府做準(zhǔn)備,為了能盡快實(shí)現(xiàn)目標(biāo)最后國家一聲令下各級(jí)政府開始同時(shí)施工,webflux也是這個(gè)思想。最后國家(spring)的命令就是webflux訂閱(真正的開始執(zhí)行),在命令沒有下達(dá)之前 各級(jí)只是根據(jù)自己負(fù)責(zé)區(qū)域?qū)嶋H情況做準(zhǔn)備并沒有實(shí)際開工(可以想象是占位,webflux中 惰性求值),各級(jí)完成了自己的任務(wù)時(shí),就報(bào)告給國家說我完成了(發(fā)射信號(hào)量),當(dāng)所有各級(jí)政府都完成了,國家就發(fā)布公告說 南水北調(diào)已經(jīng)完成請驗(yàn)收(spring數(shù)據(jù)匯總返回)。那么各級(jí)政府修建的河道成不成呢,那就讓水在挨個(gè)地區(qū)修建的河道流動(dòng)起來(對(duì)應(yīng)webflux里每個(gè)下級(jí)需要上級(jí)返回的數(shù)據(jù)流),如果說中間有個(gè)地區(qū)放下了水閘,對(duì)不起你這是在抗命啊,水在到達(dá)目的地之前是不能被攔截在一個(gè)地方的(流是不能中斷的),
總結(jié)一下一個(gè)請求進(jìn)來到出去,中間不能執(zhí)行(subscribe(),block())中斷操作,理論上最后的訂閱要交給Spring來幫我們訂閱,也就是 請求從進(jìn)來到返回,中間是不真正執(zhí)行的,只有當(dāng)Spring執(zhí)行了訂閱subscribe()以后才真正的開始執(zhí)行
4.在入門寫代碼時(shí) 如果發(fā)現(xiàn)有方法沒執(zhí)行,找找代碼中是不是沒有吧流一級(jí)一級(jí)的返回
5.如果說 一個(gè)方法你有10步操作,你想在第4步驟執(zhí)行subscribe,對(duì)不起 剩下的9個(gè)你也都加上吧,還是那句話? 流是不能被中斷的