1. Netty-Netty對Reactor 模式的支持

NIO 服務(wù)端 ServerSocketChannel 啟動步驟

  1. 創(chuàng)建
  • 創(chuàng)建 serverSocketChannel璧南,并將其綁定到某個端口,配置為非阻塞突勇。
  • 創(chuàng)建 selector悯嗓。
  1. 注冊
  • 將 ServerSocketChannel 注冊到 selector摸柄,并監(jiān)聽 accept 事件。
  1. 等待連接
  • 調(diào)用 selector.select() 方法阻塞碍舍,直到有客戶端連接柠座。
  1. 處理 accept 事件
  • 從 selector.selectedKeys() 方法獲取客戶端連接的 socketChannel,對其進(jìn)行操作片橡。

Netty 是對 Java NIO 的封裝處理妈经,使NIO更容易被使用,但是不管怎么封裝捧书,底層也需要遵循這個步驟來啟動服務(wù)端

Reactor 模式

Doug Lea 在 《Scalable IO in Java》 中定義了三種 Reactor 模式吹泡,分別為

  1. Basic Reactor
  2. Multithreaded Reactor
  3. Multiple Reactors

Basic Reactor

Basic Reactor 如下圖所示:


Basic Reactor.png

特點(diǎn):

  • 在 Basic Reactor 中,不管是處理 serverSocketChannel 的 accept 事件 還是處理 socketChannel 的 read/write 等事件经瓷,都是在同一個線程中進(jìn)行的

缺點(diǎn):

  • 資源利用率低爆哑,一個線程處理所有的請求,無法有效利用CPU

Multithreaded Reactor

Multithreaded Reactor 如下圖所示:

Multithreaded Reactor.png

特點(diǎn):

  • 當(dāng) selector 返回 serverSocketChannel 的 accept 事件后了嚎,由 main 線程處理該事件
  • 當(dāng) selector 返回 socketChannel 的 read/write 事件后泪漂,將該事件讓 ThreadPool 分配的線程來處理

優(yōu)點(diǎn):

  • 將 accept 事件和 read/write 事件分開處理,有效利用CPU資源

缺點(diǎn):

  • 一個 selector 輪詢所有事件歪泳,當(dāng)需要處理很多socketChannel 的 read/write 事件時,部分 serverSocketChannel 的 accept 會阻塞露筒,未能有效處理客戶端的連接請求

Multiple Reactors

Multiple Reactors 如下圖所示:


Multiple Reactors.png

特點(diǎn):

  1. 有兩個 seletcor呐伞,main selector 和 sub selector
  2. 將 serverSocketChannel 注冊到 main selector 中,并讓 main selctor
    監(jiān)聽 accept 事件慎式,當(dāng)返回 accept 事件時伶氢,使用 main 線程進(jìn)行處理
  3. 將 socketChannle 注冊到 sub selector 中,讓 sub selector 監(jiān)聽 read/write 等事件瘪吏,當(dāng)返回 read/write事件時癣防,將事件給 ThreadPool 分配的線程處理

優(yōu)點(diǎn):

  1. 當(dāng) server 與很多 client 進(jìn)行讀寫操作時,并不會阻塞 main selector的 accept 事件處理掌眠,使accept 事件能夠得到及時處理

Netty 對 Reactor 模式的支持

Netty 對三種 Reactor 模式都能進(jìn)行處理蕾盯,只需要對 ServeBootstrap 分配不同配置的 NioEventLoopGroup即可

Netty 對 Basic Reactor 的支持

EventLoopGroup group = new NioEventLoopGroup(1);

ServerBootstrap b = new ServerBootstrap();
           b.group(group)
           ...
  • NioEventLoopGroup 其實(shí)是 NioEventLoop 的線程集合,在 NioEventLoopGroup 是包含1個或者多個NioEventLoop 的線程池蓝丙。
  • 而在每個 NioEventLoop 中間级遭,包含著一個 seletor,用來監(jiān)聽 Channel 的事件渺尘。
  • 在上面代碼中挫鸽,NioEventLoopGroup 的構(gòu)造參數(shù)表示NioEventLoop線程集合的數(shù)量,在這里只分配一個 NioEventLoop鸥跟,所以就只有一個selector丢郊,將所有的Channel 都將注冊到 selector 中,NioEventLoopGroup分配了一個NioEventLoop,則說明只有一個NioEventLoopGroup的線程組里面只有一個線程枫匾,對于所有的channel都由這個線程進(jìn)行處理迅诬,故滿足了 Basic Reactor 的特性。

Netty 對 Multithreaded Reactor 的支持

  • Netty 并沒有對 Multithreaded Reactor 的支持

  • 因?yàn)樵?Netty 中婿牍,每個 NioEventLoop 都有一個 selector侈贷,SocketChannel/ServerSocketChannel 會被注冊到某一個 NioEventLoop 里面的selector中,當(dāng)這個selector 返回事件時等脂,也只會被該 NioEventLoop 所在的線程進(jìn)行處理俏蛮。

  • 而 NioEventLoopGroup 是 NioEventLoop的集合

  • 所以如果為 NioEventLoopGroup 集合里有多個 NioEventLoop,則也會創(chuàng)建多個selector上遥,每個 NioEventLoop 都會創(chuàng)建一個線程去處理selector 的事件搏屑,做不到一個 selector 監(jiān)聽的事件交給多個線程去處理。

在有些文章中說粉楚,以下代碼就是實(shí)現(xiàn)了Multithreaded Reactor

EventLoopGroup group = new NioEventLoopGroup();

ServerBootstrap b = new ServerBootstrap();
           b.group(group)
           ...

但是進(jìn)去 ServerBootstrap 源碼發(fā)現(xiàn)辣恋,其實(shí)只不過是將 group 集合中抽一個 NioEventLoop 作為 Main Reactor,group 集合里面的其他NioEventLoop 則繼續(xù)作為 Sub Reactor模软,是 Netty 對 Multiple Reactors 的支持伟骨。

    @Override
    public ServerBootstrap group(EventLoopGroup group) {
        // 此方法也是 bossGroup, workerGroup 調(diào)用的方法
        return group(group, group);
    }

    public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
        super.group(parentGroup);
        if (this.childGroup != null) {
            throw new IllegalStateException("childGroup set already");
        }
        this.childGroup = ObjectUtil.checkNotNull(childGroup, "childGroup");
        return this;
    }

Netty 對 Multiple Reactors 的支持

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup wokerGroup = new NioEventLoopGroup();

ServerBootstrap b = new ServerBootstrap();
           b.group(bossGroup, wokerGroup )
           ...
  • bossGroup 作為 Main Reactor,serverSocketChannel 將注冊accept事件到 bossGroup 里面的 NioEventLoop 中 selector 中燃异,由該 selector 輪訓(xùn) accept 事件携狭。
  • workerGroup 作為 Sub Reactor,所有的 socketChannel 會被注冊到workerGroup 里的 NioEventLoop 中 selector,這些 selector 負(fù)責(zé)輪訓(xùn) read 事件回俐,監(jiān)聽到的事件交給對應(yīng)的NioEventLoop 進(jìn)行處理逛腿。

Reactor 和 Selector:
在閱讀 Netty 源碼之前,一直以為 Reactor 就是 Selector仅颇,Multi Reactor (主從Reactor)就是一個 selector 負(fù)責(zé)監(jiān)聽 accept 事件单默,一個 selector 負(fù)責(zé)監(jiān)聽 read 事件,只不過處理 accept 事件的線程只有一個忘瓦,而處理 read 事件的線程有多個搁廓。
但是看了 Netty 源碼后發(fā)現(xiàn)并不是這樣,Reactor 其實(shí)是 selector 的線程集合政冻,一個 Reactor 可以有一個或者多個 selector枚抵,在 Netty 中,Main Reactor 只有一個 selector明场, 而 Sub Reactor 有多個 selector汽摹,每個 selector 互不影響,都只處理在自己中注冊的socketChannel

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末苦锨,一起剝皮案震驚了整個濱河市逼泣,隨后出現(xiàn)的幾起案子趴泌,更是在濱河造成了極大的恐慌,老刑警劉巖拉庶,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嗜憔,死亡現(xiàn)場離奇詭異,居然都是意外死亡氏仗,警方通過查閱死者的電腦和手機(jī)吉捶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來皆尔,“玉大人呐舔,你說我怎么就攤上這事】度洌” “怎么了珊拼?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長流炕。 經(jīng)常有香客問我澎现,道長,這世上最難降的妖魔是什么每辟? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任剑辫,我火速辦了婚禮,結(jié)果婚禮上影兽,老公的妹妹穿的比我還像新娘揭斧。我一直安慰自己,他們只是感情好峻堰,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盅视,像睡著了一般捐名。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上闹击,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天镶蹋,我揣著相機(jī)與錄音,去河邊找鬼赏半。 笑死贺归,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的断箫。 我是一名探鬼主播拂酣,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼仲义!你這毒婦竟也來了婶熬?” 一聲冷哼從身側(cè)響起剑勾,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赵颅,沒想到半個月后虽另,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饺谬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年捂刺,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片募寨。...
    茶點(diǎn)故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡族展,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出绪商,到底是詐尸還是另有隱情苛谷,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布格郁,位于F島的核電站腹殿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏例书。R本人自食惡果不足惜锣尉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望决采。 院中可真熱鬧自沧,春花似錦、人聲如沸树瞭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晒喷。三九已至孝偎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凉敲,已是汗流浹背衣盾。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留爷抓,地道東北人势决。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像蓝撇,于是被迫代替她去往敵國和親果复。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評論 2 361