Spring響應(yīng)式微服務(wù)學(xué)習(xí)-Web框架Spring WebFlux

前言
???目前Spring boot2.0技術(shù)棧分為了2個技術(shù)體系著蟹,一種是響應(yīng)式技術(shù)棧拢切,一種是傳統(tǒng)Servlet技術(shù)棧违寿。如下圖:

image.png

???在構(gòu)建微服務(wù)的時候食听,我們可以根據(jù)情況來決定3種架構(gòu)方式:
1、完全響應(yīng)式
這種方式就是從網(wǎng)關(guān)到基礎(chǔ)設(shè)施層昏名,使用的都是響應(yīng)式的框架,但目前數(shù)據(jù)庫方面只支持mongo和Cassandra及redis等阵面,如果有用到mysql的場景則暫時不適用轻局。
2、混合式
由于使用部分數(shù)據(jù)庫的場景是無法使用響應(yīng)式的样刷,比如mysql仑扑,所以在mysql以外的部分可以采用響應(yīng)式。
3置鼻、完全命令式
??使用Servlet Stack夫壁,對所有組件都支持。
最后總結(jié)響應(yīng)式和命令式的優(yōu)缺點:
??優(yōu)點:在IO密集型場景時沃疮,雖然代碼運行性能不會提升盒让,但可以有效的提升吞吐量,比如請求數(shù)據(jù)庫司蔬,或者微服務(wù)中下游服務(wù)響應(yīng)比較長邑茄,當你進行一個請求時,會用一個Pushlisher來替代阻塞的過程俊啼,調(diào)用者可以注冊這個Pushlisher肺缕,這樣的話,在之后數(shù)據(jù)庫或下一層服務(wù)返回結(jié)果的時候授帕,就會通知Publisher同木,然后Publisher會通知調(diào)用者。
??缺點:寫入的代碼和執(zhí)行的代碼分離開來跛十,導(dǎo)致閱讀和編寫代碼的難度增加彤路,對于這種異步的代碼,編寫單元測試和調(diào)試代碼都很困難芥映。
??在之前進行微服務(wù)架構(gòu)的實踐中洲尊,本人也是使用了第2種微服務(wù)架構(gòu)方式,也就是混合式奈偏,使用spring cloud gateway作為網(wǎng)關(guān)坞嘀,gateway是一款基于Spring WebFlux的網(wǎng)關(guān)組件,所以也是對WebFlux做了一下研究惊来,并為后續(xù)的構(gòu)建響應(yīng)式微服務(wù)打好基礎(chǔ)丽涩。

對比傳統(tǒng)的Spring WebMVC和響應(yīng)式Spring WebFlux

image.png

??在圖中,左側(cè)為spring-webmvc的技術(shù)棧裁蚁,右側(cè)為spring-webflux的技術(shù)棧矢渊。Spring WebFlux是基于響應(yīng)式流的检眯,因此,可以建立異步的昆淡、非阻塞的锰瘸、事件驅(qū)動的服務(wù)。它采用Reactor作為首選的響應(yīng)式流的實現(xiàn)庫昂灵,并且也提供了對RxJava的支持避凝。而傳統(tǒng)的Spring WebMVC構(gòu)建在Java EE的servlet標準之上,該標準本身就是阻塞式和同步的眨补。在最新版的Servlet中也添加了異步支持管削,但是在等待請求的過程中,Servlet仍然在線程池中保持著線程撑螺。
Spring-WebFlux可以運行在Tomcat含思,Jetty,Netty甘晤,Undertow含潘,Servlet3.1+等多個容器上,默認使用Netty线婚。這里要提一個在Spring cloud gateway使用時遇到的容器的坑遏弱,gateway只能運行在netty上,否則qps會大大下降塞弊。參照我的文章:http://www.reibang.com/p/dde1b00cbbaa

Spring MVC和Spring WebFlux的關(guān)系
??請看下圖漱逸,既有共同的部分,也有互相獨立的部分游沿。

image.png

WebFlux的使用場景
??在微服務(wù)架構(gòu)體系中饰抒,WebFlux和WebMVC可以混合使用。而在IO密集型服務(wù)時诀黍,我們可以優(yōu)先選擇WebFlux去實現(xiàn)袋坑。比如web網(wǎng)關(guān)spring cloud gateway就是使用了基于WebFlux的實現(xiàn),在運行時間上蔗草,響應(yīng)式和非阻塞并不能讓程序運行的更快咒彤,相反還要稍微增加一些處理時間疆柔,可能還會稍微變慢咒精,那么gateway為什么要用它呢,因為網(wǎng)關(guān)是一個IO密集型服務(wù)旷档,如果下層服務(wù)的網(wǎng)絡(luò)變慢或不可靠模叙,那么響應(yīng)式所能體現(xiàn)出來的巨大差異就顯示出來了。

說回WebFlux
??前邊說過WebFlux采用Reactor作為首選的響應(yīng)式流的實現(xiàn)庫鞋屈,Mono和Flux是Reactor中兩個基礎(chǔ)概念范咨,Mono包含了0..1個元素序列故觅,F(xiàn)lux包含了0..N個元素序列。Mono和Flux都是發(fā)布者渠啊,實現(xiàn)了Publisher<T>输吏。在WebFlux中,方法只返回Mono和Flux替蛉,代碼基本也只和 Mono 或 Flux 打交道贯溅。而 Web Flux 則會實現(xiàn) Subscriber ,onNext 時將業(yè)務(wù)開發(fā)人員編寫的 Mono 或 Flux 轉(zhuǎn)換為 HTTP Response 返回給客戶端躲查。WebFlux有兩種不同的編程風(fēng)格它浅,分別是基于Spring MVC的注解和基于函數(shù)式路由。

基于Spring MVC

@RestController
public class HelloController {
    @RequestMapping("sayOneHello")
    public Mono<String> sayOneHello() {
        return Mono.just("Hello World");
    }

    @RequestMapping("sayMoreHello")
    public Flux<String> sayMoreHello() {
        return Flux.fromIterable(new ArrayList<String>() {
            {
                add("Hello World one");
                add("Hello World two");
                add("Hello World three");
            }
        });
    }
}

基于函數(shù)式路由

@Component
public class HelloWorldHandlerFunction {

    public Mono<ServerResponse> hello(ServerRequest serverRequest) {
        return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(
                BodyInserters.fromValue("Hello World"));
    }
}

@Configuration
public class HelloWorldRouter {
    @Bean
    public RouterFunction<ServerResponse> routeHelloWorld(HelloWorldHandlerFunction helloWorldHandlerFunction) {
        return RouterFunctions.route(RequestPredicates.GET("/hello").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
                helloWorldHandlerFunction::hello);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末镣煮,一起剝皮案震驚了整個濱河市姐霍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌典唇,老刑警劉巖镊折,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異介衔,居然都是意外死亡腌乡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門夜牡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來与纽,“玉大人,你說我怎么就攤上這事塘装〖庇兀” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵蹦肴,是天一觀的道長僚碎。 經(jīng)常有香客問我,道長阴幌,這世上最難降的妖魔是什么勺阐? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮矛双,結(jié)果婚禮上渊抽,老公的妹妹穿的比我還像新娘。我一直安慰自己议忽,他們只是感情好懒闷,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般愤估。 火紅的嫁衣襯著肌膚如雪帮辟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天玩焰,我揣著相機與錄音由驹,去河邊找鬼。 笑死昔园,一個胖子當著我的面吹牛荔棉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蒿赢,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼润樱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了羡棵?” 一聲冷哼從身側(cè)響起壹若,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎皂冰,沒想到半個月后店展,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡秃流,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年赂蕴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舶胀。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡概说,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嚣伐,到底是詐尸還是另有隱情糖赔,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布轩端,位于F島的核電站放典,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏基茵。R本人自食惡果不足惜奋构,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拱层。 院中可真熱鬧弥臼,春花似錦、人聲如沸舱呻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽箱吕。三九已至芥驳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間茬高,已是汗流浹背兆旬。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留怎栽,地道東北人丽猬。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像熏瞄,于是被迫代替她去往敵國和親脚祟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359