我最近开始使用JBoss Netty,到目前为止,我的理解是channelPipelineFactory用于在每次服务器接收请求时创建ChannelPipeline。ChannelPipeline包含一系列处理请求的ChannelHandlers。现在我的问题是,如果管道中的一个处理程序需要从数据库中获取数据,这就是阻塞I/O。请求的处理被阻止了?这与Servlet的常规请求处理有什么不同?我对来自NodeJS的事件驱动异步I/O的理解是,有一个事件循环,有一系列注册用于阻塞I/O操作的回调函数,这些函数在I/O完成时被调用。在Netty中对应的是什么?
private static final HttpResponseEncoder httpResponseEncoder = new HttpResponseEncoder();
private static final JsonEncoder jsonEncoder = new JsonEncoder();
private static final ExecutionHandler executionHandler = new ExecutionHandler(
new OrderedMemoryAwareThreadPoolExecutor(5, 1048576, 1048576));
public static void main(String[] args) throws Exception {
ChannelFactory factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
SocketAddress sockAddress = new InetSocketAddress(8080);
RedisClient client = new RedisClient("127.0.0.1");
final RedisAsyncConnection<String, String> connection = client.connectAsync();
ServerBootstrap bootstrap = new ServerBootstrap(factory);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("executionHandler", executionHandler);
pipeline.addLast("weightedRandomGenerator", new WeightedRandomNumberGenerator(
connection));
pipeline.addLast("encoder", httpResponseEncoder);
pipeline.addLast("JsonConverter", jsonEncoder);
return pipeline;
}
});
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.keepAlive", true);
bootstrap.bind(sockAddress);
}
如果您需要运行阻塞操作,您需要在执行阻塞操作的ChannelHandler前面放置一个ExecutorHandler。这会将EventLoop (IO-Thread)中的所有ChannelHandlers"移动"到另一个线程中,从而"解除"EventLoop的阻塞。
看到[1]
[1] http://netty.io/3.6/api/org/jboss/netty/handler/execution/ExecutionHandler.html