Netty快速入門(10)Reactor與Netty

Reactor模式

Reactor是1995年由道格拉斯提出的一種高性能網(wǎng)絡(luò)編程模式但壮。由于好多年了粪薛,當(dāng)時的一些概念與現(xiàn)在略有不同著蟹,reactor模式在網(wǎng)絡(luò)編程中是非常重要的煞肾,可以說是NIO框架的典型模式命贴,一些經(jīng)典的框架道宅,比如Mina、Netty胸蛛、Cindy都是此模式的實現(xiàn)污茵。

我們來看看當(dāng)年提出的通用模型:

上面的圖形中:

1、Handle 可以理解為資源或者文件句柄葬项,放在netty里面就是channel泞当,就是我們實際要處理的東西

2、Event Handler和Concrete Event Handler 就是具體的事件處理器民珍,對應(yīng)netty中的handler接口和具體的handler

3襟士、Synchronous Event Demultiplexer同步事件多路復(fù)用分發(fā)器,可以理解為nio中的select

4嚷量、Initiation Dispatcher陋桂,分發(fā)器,可以理解為nio中的循環(huán)蝶溶,也就是netty中的EventLoop嗜历,處理各種事件

5、select(handlers)就是真正處理業(yè)務(wù)的地方

大家注意上面圖形中的幾個箭頭抖所,可以看出各個組件之間的關(guān)聯(lián)關(guān)系梨州。這個經(jīng)典的模型當(dāng)時并不是針對Java提出的,任何擁有這些組件的語言部蛇,都可以實現(xiàn)高性能的reactor模型摊唇。




單線程Reactor

基于Java,Doug Lea(Java并發(fā)包作者)提出了三種形式涯鲁,單線程Reactor巷查,多線程Reactor和Multiple Reactor。首先看一下基本的單線程模式:

單線程模型就是一個reactor(select+循環(huán))抹腿,客戶端(client)注冊進(jìn)來由reactor接收注冊事件岛请,然后再由reactor分發(fā)(dispatch)出去,由下面的處理器(read警绩、decode崇败、compute等)去處理。我們前面復(fù)習(xí)nio代碼的時候,程序就是這樣的結(jié)構(gòu)后室,只有一個select缩膝。





多線程Reactor

單線程的Reactor有明顯的不足,只有一個線程岸霹,又要接收連接疾层,又要處理io讀寫,還要處理計算和業(yè)務(wù)邏輯贡避,如果是io密集型還行痛黎,如果是計算密集型效率會很慢。現(xiàn)在的機(jī)器都是多核的刮吧,只用一個線程也浪費機(jī)器資源湖饱,無法充分利用機(jī)器。多線程Reactor能解決這個問題杀捻,來看一下多線程Reactor模型:

在多線程Reactor中井厌,注冊接收事件都是由Reactor來做,其它的計算致讥,編解碼由一個線程池來做旗笔。單獨一個線程接收請求,另一個線程池處理其它業(yè)務(wù)拄踪。這種模型的問題就是蝇恶,使用線程池處理的時候,很多地方會有多次線程切換惶桐,上下文切換撮弧,導(dǎo)致效率比較低,有很多問題要處理姚糊,甚至光是接收和讀寫等請求一個線程也可能忙不過來贿衍,因此有了第三種模式,就是Multiple Reactor救恨。





Multiple Reactor

這種模式特點是有多個Reactor贸辈,一個boss Reactor負(fù)責(zé)接收,另外幾個worker? Reactor負(fù)責(zé)讀寫肠槽,把業(yè)務(wù)部分的處理還是放到線程池中來做擎淤。我們前面討論的netty示例代碼其實就是這樣的模型:

netty中的handler默認(rèn)沒有啟用線程池,如果我們定義用線程池去處理秸仙,那么就和上面的模型幾乎一模一樣了嘴拢。上面的三種Reactor模式就是最基本的Java的三種Reactor模式。


網(wǎng)上關(guān)于Reactor的內(nèi)容有很多寂纪,分的類型也更細(xì)一些席吴,擴(kuò)展了很多其它的形式赌结,針對具體的場景有一些更加詳細(xì)的模式,比如下面的主從Reactor模式:

在主從Reactor模式中孝冒,再次對Reactor進(jìn)行細(xì)分柬姚,有一個主要的Reactor進(jìn)行接收,里面可以做一些認(rèn)證登錄之類的事情庄涡,完了之后再分配到Sub Reactor下面去伤靠,再做具體的IO處理。

網(wǎng)上關(guān)于Reactor模型有很多啼染,但是Java經(jīng)典的三種最基本的一定要了解清楚,我們設(shè)計自己的架構(gòu)的時候焕梅,不要被網(wǎng)上過多的五花八門的模型擾亂迹鹅,從基本模型觸發(fā)就可以。





Netty支持的Reactor形式

netty其實對三種Java基本的Reactor模式都是支持的贞言。我們前面演示過斜棚,netty啟動時,要在ServerBootstrap中配置bossGroup和childGroup兩個EventLoopGroup该窗,也就是說netty是可以靈活配置的弟蚀。我們通過配置可以讓netty分別實現(xiàn)對三種模式的支持。

先看一下對單線程reactor的配置:

在配置的時候酗失,boss和worker兩個group配置成一個义钉,也就是說兩個group的工作交給一個bossGroup(線程數(shù)為1)來完成。這樣實際上就是第一個單線程reactor的模型规肴。上面的代碼就是對第一種模式的支持捶闸。

再來看一下對第二種多線程reactor模式的支持,其實第二種模式和第一種代碼的配置是一樣的拖刃,只是在handler中進(jìn)行處理的時候删壮,使用一個線程池處理所有業(yè)務(wù),這樣就是第二種多線程的reactor模式兑牡。

第三種Multiple Reactor模式是我們用的最多的模式央碟,也是前面例子演示中的配置形式。boss為單線程均函,worker為多線程亿虽,在ServerBootstrap中同時配置boss和worker,下面是我們熟悉的代碼:

EventLoopGroup如果沒有配置線程數(shù)量苞也,默認(rèn)創(chuàng)建cpu個數(shù)的兩倍经柴,所以上面worker的線程數(shù)根據(jù)機(jī)器決定。但是現(xiàn)在如果要嚴(yán)格對應(yīng)第三種模式墩朦,在handler中坯认,還要加上線程池。如果計算不太復(fù)雜,一個workerGroup就可以了牛哺,如果需要很復(fù)雜的計算陋气,建議在handler中加入線程池進(jìn)行處理。盡量不要讓IO線程池阻塞引润。?


在很多netty項目中巩趁,還有這樣的寫法:

boss和worker中的線程數(shù)都是多個,這種配置并沒有對應(yīng)前面提過的任何一種模式淳附,那么會有這種需要使用多個boss線程的情況嗎议慰?我們知道accept只能保存到一個線程上,所以說bossGroup配置多個是沒有用的奴曙,所以也有人問netty框架的作者别凹,這種什么時候會用到,下面是作者的回答:

大致是說洽糟,這種配置不是必須的炉菲,但是它可能會非常有用,比如當(dāng)多個ServerBootstrap共享一個NioEventLoopGroup的時候會非常有用坤溃,意思就是拍霜,每個ServerBootstrap都要注冊一個NioServerSocketChannel,如圖:

如果多個ServerBootstrap都使用一個bossGroup薪介,這時候bossGroup初始化為1個線程祠饺,就意味著一個線程監(jiān)聽多個端口,這樣顯然不太好汁政,這時候bossGroup就可以配置成多個吠裆,這樣可以每個端口由一個線程去監(jiān)聽,提高效率烂完。

但是试疙,上面是想象中的使用情況,我們實際開發(fā)netty的時候抠蚣,幾乎沒有看到有多個ServerBootstrap的情況祝旷,所以bossGroup配置成多個在現(xiàn)在看來幾乎是沒有用的,我們把bossGroup的參數(shù)直接寫成1就可以嘶窄。即使寫成了8怀跛,實際執(zhí)行的時候,也只會用到一個線程柄冲,ServerBootstrap只會使用一個吻谋,不會使用多個。


關(guān)于主從reactor模式现横,從目前netty看沒有辦法通過配置直接實現(xiàn)漓拾。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阁最,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子骇两,更是在濱河造成了極大的恐慌速种,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件低千,死亡現(xiàn)場離奇詭異配阵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)示血,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門棋傍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人难审,你說我怎么就攤上這事瘫拣。” “怎么了剔宪?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長壹无。 經(jīng)常有香客問我葱绒,道長,這世上最難降的妖魔是什么斗锭? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任地淀,我火速辦了婚禮,結(jié)果婚禮上岖是,老公的妹妹穿的比我還像新娘帮毁。我一直安慰自己,他們只是感情好豺撑,可當(dāng)我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布烈疚。 她就那樣靜靜地躺著,像睡著了一般聪轿。 火紅的嫁衣襯著肌膚如雪爷肝。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天陆错,我揣著相機(jī)與錄音灯抛,去河邊找鬼。 笑死音瓷,一個胖子當(dāng)著我的面吹牛对嚼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播绳慎,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼纵竖,長吁一口氣:“原來是場噩夢啊……” “哼漠烧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起磨确,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤沽甥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后乏奥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摆舟,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年邓了,在試婚紗的時候發(fā)現(xiàn)自己被綠了恨诱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡骗炉,死狀恐怖照宝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情句葵,我是刑警寧澤厕鹃,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站乍丈,受9級特大地震影響剂碴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜轻专,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一忆矛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧请垛,春花似錦催训、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至混稽,卻和暖如春嫂侍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荚坞。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工挑宠, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颓影。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓各淀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親诡挂。 傳聞我的和親對象是個殘疾皇子碎浇,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容