Java併發編程學習-日記5、Netty從DiscardServer實踐開始

DiscardServer所示,創建netty服務端,一共有8步,重點在:監控事件的線程組、通道及通道參數、出入站的處理器(綁定在流水線上)、異步監控事件處理

public class NettyDiscardServer {

    private final int serverPort;

    /*

Netty的服務啓動類ServerBootstrap,它的職責是一個組裝和集成器,將不同的Netty組件組裝在一起。另外,ServerBootstrap能夠按照應用場景的需要,爲組件設置好對應的參數,最後實現Netty服務器的監聽和啓動。Netty中的各種組件:服務器啓動器、緩衝區、反應器、Handler業務處理器、Future異步任務監聽、數據傳輸通道。

     */

    ServerBootstrap b = new ServerBootstrap();//Netty服務端啓動器

    public NettyDiscardServer(int port) {

        this.serverPort = port;

    }

    public void runServer() {

        //創建reactor 線程組,創建兩個線程組僅僅是爲了能夠及時的接收到新建連接,

        // 如果將連接監聽和事件處理放在同一線程組中,可能會因爲事件處理較爲耗時,而堵塞連接

        EventLoopGroup bossLoopGroup = new NioEventLoopGroup(1); //負責服務器通道新連接的IO事件監聽

        EventLoopGroup workerLoopGroup = new NioEventLoopGroup();//負責傳輸通道的IO事件處理

        try {

            b.group(bossLoopGroup, workerLoopGroup); //1 設置reactor 線程組

            //2 設置nio類型的channel,當然也可設置爲堵塞通道b.channel(OioServerSocketChannel.class);

            b.channel(NioServerSocketChannel.class);

            //3 設置監聽端口

            b.localAddress(serverPort);

            //4 設置通道的參數,option()用於給【父通道】選項設置,childOption()用於【子通道】選項設置

            b.option(ChannelOption.SO_KEEPALIVE, true);

            b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);

            b.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);

            //5 裝配【子通道】流水線:這個流水線日後筆記中會詳細說明,流水線用於組織處理器,使得消息在入站後,出站前的一些列處理。類似流與java異常鏈。

            b.childHandler(new ChannelInitializer<SocketChannel>() {

                //有連接到達時會創建一個channel

                protected void initChannel(SocketChannel ch) throws Exception {

                    // pipeline管理子通道channel中的Handler, 向子channel流水線添加一個handler處理器

                    ch.pipeline().addLast(new NettyDiscardHandler());

                }

            });

            // 6 開始綁定server,通過調用sync同步方法阻塞直到綁定成功,ChannelFuture繼承Java的Future接口,用於異步監控,後續筆記中會詳細說明。

            ChannelFuture channelFuture = b.bind().sync();

            Logger.info(" 服務器啓動成功,監聽端口: " + channelFuture.channel().localAddress());

            // 7 等待通道關閉的異步任務結束

            // 服務監聽通道會一直等待通道關閉的異步任務結束

            ChannelFuture closeFuture = channelFuture.channel().closeFuture();

            closeFuture.sync();

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            // 8 優雅關閉EventLoopGroup

            // 釋放掉所有資源包括創建的線程

            workerLoopGroup.shutdownGracefully();

            bossLoopGroup.shutdownGracefully();

        }

    }

    public static void main(String[] args) throws InterruptedException {

        new NettyDiscardServer(9000).runServer();

    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章