关于Netty使用是两个ChildHandler与使用异步线程的效率问题


在编写 Server 端代码的时候我有这样的需求,将接收到的数据缓存到本地,同时也要将数据推送到远端的数据库,为了不互相影响。
第一种做法就是在缓存数据的 handler 中起一个线程去推送数据。


 public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(); 
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap(); 
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class) 
             .childHandler(new ChannelInitializer<SocketChannel>() { 
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new ObjectDecoder(1024 * 1024, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));
                     ch.pipeline().addLast(new ObjectEncoder());

                     ch.pipeline().addLast(new MyServerHandler()); // (1)
                     //ch.pipeline().addLast(new MyServerHandler2()); // (2)
                 }
             })
             .option(ChannelOption.SO_BACKLOG, 128)          
             .childOption(ChannelOption.SO_KEEPALIVE, true); 

            ChannelFuture f = b.bind(port).sync(); 

            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }


 public class MyServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        //缓存到本地
        new Thread(new Runnable() { 
            //推送到远端数据库
        }).start();
    }
}

第二种做法就是使用两个 handler ,在第一个 handler 处理完后,调用一次 ctx.fireChannelRead(msg); 触发第二个 handler .


 ch.pipeline().addLast(new MyServerHandler()); // (1)
ch.pipeline().addLast(new MyServerHandler2()); // (2)


 public class MyServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        //缓存到本地
        ctx.fireChannelRead(msg);
    }
}


 public class MyServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        //推送到远端数据库
    }
}

目前可以看出来的是,第一种做法涉及到创建线程销毁线程,会有一定的开销,那么第二种做法又有什么不好的地方么?

java netty

saber吾妻 9 years, 8 months ago

Your Answer