2019-05-16 netty 服務(wù)端啟動(dòng)

以netty源碼中的為EchoServer例佳励,分析netty服務(wù)端啟動(dòng)的流程

public final class EchoServer {

    public static void main(String[] args) throws Exception {
        // Configure the server.
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 100)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline p = ch.pipeline();
                            p.addLast(new LoggingHandler(LogLevel.INFO));
                            p.addLast(new EchoServerHandler());
                        }
                    });

            // Start the server.
            ChannelFuture f = b.bind(8007).sync();

            // Wait until the server socket is closed.
            f.channel().closeFuture().sync();
        } finally {
            // Shut down all event loops to terminate all threads.
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

首先在ServerBootstrap調(diào)用group方法的時(shí)候會(huì)傳進(jìn)去兩組group線程組袍辞;


image.png

調(diào)用父類的構(gòu)造器設(shè)置group屬性


image.png

這兩個(gè)group線程會(huì)分別賦給group和childGroup兩個(gè)屬性;


image.png
image.png
image.png

這里的childGroup 是由EventLoopGroup workerGroup = new NioEventLoopGroup()初始化的足丢,默認(rèn)會(huì)創(chuàng)建兩倍cpu核數(shù)的NioEventLoop線程數(shù)量;

image.png

繼續(xù)走調(diào)用channel()方法,會(huì)創(chuàng)建一個(gè)ReflectiveChannelFactory,這里傳進(jìn)去的就是class io.netty.channel.socket.nio.NioServerSocketChannel這個(gè)class;


image.png

同時(shí)設(shè)置channelFactory屬性為為NioServerSocketChannel.class提鸟;


image.png

接下來就是設(shè)置一些屬性,handler仅淑,childHandler称勋,這里不再展開;

繼續(xù)走涯竟,看調(diào)用bind方法的時(shí)候


image.png

最終會(huì)調(diào)用到io.netty.bootstrap.AbstractBootstrap#doBind方法


image.png

調(diào)用initAndRegister 初始化channel并且進(jìn)行注冊selector赡鲜;
首先看初始化Channel部分,調(diào)用this.channelFactory.newChannel();方法


image.png
image.png

其實(shí)這里的clazz就是class io.netty.channel.socket.nio.NioServerSocketChannel庐船,其實(shí)創(chuàng)建的channel對象就是NioServerSocketChannel银酬;

接下來我們在看看NioServerSocketChannel的構(gòu)造函數(shù)做了什么?

image.png
image.png

調(diào)用newSocket方法,通過jdk底層SelectorProvider.provider().openServerSocketChannel()來創(chuàng)建jdk ServerSocketChannel筐钟;

image.png

接下來調(diào)用構(gòu)造函數(shù)初始化屬性配置揩瞪,其實(shí)就是設(shè)置ServerSocketChannelConfig


image.png

設(shè)置unsafe,id,pipeline等參數(shù),其實(shí)在這里就已經(jīng)確定了這個(gè)channel屬于哪個(gè)pipeline; 客戶端創(chuàng)建channel也是一樣的;


image.png

初始化channel


image.png

配置config


image.png

以下便是這個(gè)config的屬性配置


image.png

以上就是服務(wù)端channel的創(chuàng)建過程篓冲,接下來就是服務(wù)端channel的初始化過程
1.設(shè)置option屬性值李破,把它設(shè)置到config中去


image.png
image.png

2.設(shè)置channel的attr屬性


image.png

3.為pipeline設(shè)置handler,ChannelHandler handler = ServerBootstrap.this.config.handler();去除BootStrap中配置的handler壹将,然后添加到Pipeline中

image.png

4.添加一個(gè)ServerBootstrapAcceptor嗤攻,其實(shí)這是一個(gè)特殊的channelHandler,
傳入的一個(gè)work線程組,handler,attr和options等屬性;


image.png

channel注冊到selector


image.png

this.config().group()這個(gè)其實(shí)就是boss線程綁定channel,代碼位置io.netty.channel.AbstractChannel.AbstractUnsafe#register;

image.png

在看register0方法實(shí)現(xiàn)


image.png
image.png

調(diào)用jdk底層進(jìn)行注冊诽俯,每隔NioEventLoop都有一個(gè)Selector屬性


image.png

結(jié)下來AbstractChannel.this.pipeline.invokeHandlerAddedIfNeeded();會(huì)調(diào)用到io.netty.channel.DefaultChannelPipeline.PendingHandlerAddedTask#execute從而會(huì)觸發(fā)io.netty.channel.ChannelHandlerAdapter#handlerAdded方法的調(diào)用

這行代碼AbstractChannel.this.pipeline.fireChannelRegistered();會(huì)觸發(fā)
io.netty.channel.ChannelInboundHandler#channelRegistered事件的調(diào)用妇菱;

繼續(xù)看doBind方法


image.png

io.netty.channel.AbstractChannel.AbstractUnsafe#bind


image.png

最終通過NioServerSocketChannel 進(jìn)行端口綁定,調(diào)用jdk底層的方法


image.png

最后觸發(fā)ChannelActive事件,調(diào)用readIfIsAutoRead()方法處理客戶端鏈接事件

image.png

感興趣的可以去跟下代碼闯团,這個(gè)read會(huì)在pipeline上不斷的傳播


image.png

有一個(gè)自動(dòng)讀的配置其實(shí)是在初始化ServerBootstrapAcceptor配置的


image.png
image.png
image.png

這里的readInterestOp 其實(shí)就是NioServerSocketChannel構(gòu)造函數(shù)中傳入的16


image.png

到此辛臊,服務(wù)端啟動(dòng)的代碼走讀就完了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末偷俭,一起剝皮案震驚了整個(gè)濱河市浪讳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涌萤,老刑警劉巖淹遵,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異负溪,居然都是意外死亡透揣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門川抡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辐真,“玉大人,你說我怎么就攤上這事崖堤∈淘郏” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵密幔,是天一觀的道長楔脯。 經(jīng)常有香客問我,道長胯甩,這世上最難降的妖魔是什么昧廷? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮偎箫,結(jié)果婚禮上木柬,老公的妹妹穿的比我還像新娘。我一直安慰自己淹办,他們只是感情好眉枕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著怜森,像睡著了一般齐遵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上塔插,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機(jī)與錄音拓哟,去河邊找鬼想许。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的流纹。 我是一名探鬼主播糜烹,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼漱凝!你這毒婦竟也來了疮蹦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤茸炒,失蹤者是張志新(化名)和其女友劉穎愕乎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體壁公,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡感论,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了紊册。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片比肄。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖囊陡,靈堂內(nèi)的尸體忽然破棺而出芳绩,到底是詐尸還是另有隱情,我是刑警寧澤撞反,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布妥色,位于F島的核電站,受9級特大地震影響痢畜,放射性物質(zhì)發(fā)生泄漏垛膝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一丁稀、第九天 我趴在偏房一處隱蔽的房頂上張望吼拥。 院中可真熱鬧,春花似錦线衫、人聲如沸凿可。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽枯跑。三九已至,卻和暖如春白热,著一層夾襖步出監(jiān)牢的瞬間敛助,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工屋确, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纳击,地道東北人续扔。 一個(gè)月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像焕数,于是被迫代替她去往敵國和親纱昧。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354

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