关于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 {
//推送到远端数据库
}
}
目前可以看出来的是,第一种做法涉及到创建线程销毁线程,会有一定的开销,那么第二种做法又有什么不好的地方么?
saber吾妻
9 years, 8 months ago