Netty中Reactor模型的實現


在Netty中,能夠同時支持單線程,多線程和主從Reactor三種模式:

下圖為Netty的線程模型:

 

以常用的Netty代碼舉例分析:

// 配置服務端的NIO線程組
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    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) {
                // ch.pipeline().addLast(
                // new ProtobufVarint32FrameDecoder());
                ch.pipeline().addLast(
                    new ProtobufDecoder(
                        SubscribeReqProto.SubscribeReq
                            .getDefaultInstance()));
                ch.pipeline().addLast(
                    new ProtobufVarint32LengthFieldPrepender());
                ch.pipeline().addLast(new ProtobufEncoder());
                ch.pipeline().addLast(new SubReqServerHandler());
            }
            });

        // 綁定端口,同步等待成功
        ChannelFuture f = b.bind(port).sync();

        // 等待服務端監聽端口關閉
        f.channel().closeFuture().sync();
    } finally {
        // 優雅退出,釋放線程池資源
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }

以上服務端啟動,創建了兩個EventLoopGroup,實際上就是兩個Selector線程組。其中boss線程組負責接收客戶端連接,work線程組負責處理IO操作和系統Task和定時任務的調度。每個EventLoopGroup里面都維護了一個selector。

為了減少鎖競爭,Netty的work線程組處理IO操作時,都是單線程的,如圖下圖所示:

 

如圖,work線程組接收到讀事件時,將讀事件往pipeline從頭到尾傳遞,處理完數據后,將寫事件往pipeline從尾到頭傳遞,整個過程都是同一條線程,避免了多線程操作,也避免了鎖競爭帶來的性能消耗。

EventLoopGroup的簡析:
  EventLoopGroup是一個不僅具備IO操作線程,還具體系統Task和定時任務的調度的功能的線程組。

 
        
EventLoopGroup內部維護了一個selector,因此會出現空輪詢的bug,netty通過周期性的對select()為0的情況進行計數,當出現次數達到一定值,
則認為出現空輪詢的bug,此時會重新打開一個新的selector,將舊的替換掉。


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM