我正在构建一个基于 Netty 的小型应用程序,该应用程序通过套接字连接(即 telnet/ssh)执行 I/O 操作。我正在使用 Netty 启动我的套接字服务器ServerBootstrap
类,给出:
类型的事件循环NioEventLoopGroup
(即不应遭受阻塞操作的共享线程池)。
类型通道NioServerSocketChannel
(我相信这需要与上面的#1相对应)。
一个非常简单的管道,带有扩展的通道处理程序ChannelInboundHandlerAdapter
.
我的处理程序channelRead(...)
每当从客户端套接字连接接收到命令字符串时,就会调用该方法,并根据命令返回一些响应字符串。
对于不涉及阻塞操作的命令来说一切都很好。但是,我现在需要从数据库中读取或写入一些命令。这些 JDBC 调用本质上会被阻塞......尽管我could use a CompletableFuture
(或其他)在单独的线程中处理它们。
但即使我通过在单独的线程中执行阻塞操作来“滚动我自己的异步”,我也不确定如何将这些生成的线程的结果重新连接回主线程中的 Netty 通道处理程序。
我看到ChannelHandlerContext
类具有如下方法:
ChannelFuture writeAndFlush(Object msg, ChannelPromise promise);
...作为我当前使用的替代品:
ChannelFuture writeAndFlush(Object msg);
但我找不到任何文档或指南(甚至有用的 Javadocs)来解释如何使用它ChannelPromise
在此用例中键入。它的名字表明它might相关,但也可能不相关。毕竟,writeAndFlush
方法仍然将传出消息作为其第一个参数...那么,如果您需要第一个参数的结果已经在手边,那么将阻塞操作填充到“promise”第二个参数中会有什么好处呢?
这里什么才是正确的道路?是否有某种方法可以在单独的线程中处理阻塞操作,以便 Netty 的NioEventLoopGroup
不阻塞?或者这根本不是 Netty 的工作方式,如果您需要支持阻塞,您应该使用不同的事件循环实现(即为每个客户端套接字连接生成一个单独的线程)?
如果 Netty 中的操作需要较长时间才能完成或阻塞,建议在handler that uses a separate ExecutorGroup
这样主EventLoop线程就不会被阻塞。
您可以在管道创建期间指定。
引用一个使用执行器组进行数据库操作的示例ChannelPipeline javadoc http://netty.io/4.1/api/io/netty/channel/ChannelPipeline.html
static final EventExecutorGroup group = new DefaultEventExecutorGroup(16);
...
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("decoder", new MyProtocolDecoder());
pipeline.addLast("encoder", new MyProtocolEncoder());
// Tell the pipeline to run MyBusinessLogicHandler's event handler methods
// in a different thread than an I/O thread so that the I/O thread is not blocked by
// a time-consuming task.
// If your business logic is fully asynchronous or finished very quickly, you don't
// need to specify a group.
pipeline.addLast(group, "handler", new MyBusinessLogicHandler());
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)