Java 使用Netty构建只有少量客户端的服务器
我熟悉Netty的基础知识,并使用它构建了一个典型的运行在TCP上的应用服务器,该服务器旨在为许多客户机/连接提供服务。然而,我最近有一个需求,即构建一个服务器,该服务器设计用于处理少数客户机,或者大多数情况下仅处理一个客户机。但是,客户端是许多设备的网关,因此会为我试图设计的服务器生成大量流量 我的问题是:Java 使用Netty构建只有少量客户端的服务器,java,multithreading,netty,Java,Multithreading,Netty,我熟悉Netty的基础知识,并使用它构建了一个典型的运行在TCP上的应用服务器,该服务器旨在为许多客户机/连接提供服务。然而,我最近有一个需求,即构建一个服务器,该服务器设计用于处理少数客户机,或者大多数情况下仅处理一个客户机。但是,客户端是许多设备的网关,因此会为我试图设计的服务器生成大量流量 我的问题是: 是否有可能/建议在此用例中使用Netty?我已经看到了讨论 是否可以将多线程EventExecutor用于管道中的通道处理程序,以便由EventExecutor线程池实现并发而不是通道E
- 是否有可能/建议在此用例中使用
?我已经看到了讨论Netty
- 是否可以将多线程EventExecutor用于管道中的通道处理程序,以便由EventExecutor线程池实现并发而不是通道EventLoop?它会确保来自客户端的一条消息由一个线程通过所有处理程序处理,而下一条消息由另一个线程处理吗
- 是否有可用的示例实现
OioByteStreamChannel::activate
:
/**
* Activate this instance. After this call {@link #isActive()} will return {@code true}.
*/
protected final void activate(InputStream is, OutputStream os) {
if (this.is != null) {
throw new IllegalStateException("input was set already");
}
if (this.os != null) {
throw new IllegalStateException("output was set already");
}
if (is == null) {
throw new NullPointerException("is");
}
if (os == null) {
throw new NullPointerException("os");
}
this.is = is;
this.os = os;
}
如您所见,oio流将在那里使用
根据你的评论。将处理程序添加到管道时,可以指定EventExecutorGroup
,如下所示:
new ChannelInitializer<Channel> {
public void initChannel(Channel ch) {
ch.pipeline().addLast(new YourHandler());
}
}
这里我们看到,如果您不注册EventExecutor
,它将使用您在创建ServerBootstrap
时指定的子事件组
new ServerBootstrap()
.group(new OioEventLoopGroup(), new OioEventLoopGroup())
//acceptor group //child group
下面是如何调用从通道读取的AbstractChannelHandlerContext::invokeChannelRead
:
static void invokeChannelRead(final AbstractChannelHandlerContext next, Object msg) {
final Object m = next.pipeline.touch(ObjectUtil.checkNotNull(msg, "msg"), next);
EventExecutor executor = next.executor();
if (executor.inEventLoop()) {
next.invokeChannelRead(m);
} else {
executor.execute(new Runnable() { //Invoked by the EventExecutor you specified
@Override
public void run() {
next.invokeChannelRead(m);
}
});
}
}
即使是一些连接,我也会使用NioEventLoopGroup
关于你的问题:
是否可以将多线程EventExecutor用于通道
管道中的处理程序,以便
并发是由EventExecutor线程池实现的?会吗
确保来自客户端的一条消息将由一个线程处理
通过所有处理程序,而下一条消息由另一个线程执行
Netty的通道
保证入站或出站消息的每个处理都将在同一线程中进行。您不必亲自破解事件执行器来处理此问题。如果服务入站消息不需要长时间的处理,那么您的代码将类似于ServerBootstrap
的基本用法。您可能会发现调整池中线程的数量很有用。谢谢您的回答。使用OIO时,我是否可以对管道中的处理程序使用EventExecutor
。@SoumyaKanti更新了我的答案。谢谢,对我真的很有帮助。@SoumyaKanti欢迎您。要了解如何为子频道注册EventGroup
,您可以查看私有静态类ServerBootstrapAcceptor
当然可以。
static void invokeChannelRead(final AbstractChannelHandlerContext next, Object msg) {
final Object m = next.pipeline.touch(ObjectUtil.checkNotNull(msg, "msg"), next);
EventExecutor executor = next.executor();
if (executor.inEventLoop()) {
next.invokeChannelRead(m);
} else {
executor.execute(new Runnable() { //Invoked by the EventExecutor you specified
@Override
public void run() {
next.invokeChannelRead(m);
}
});
}
}