Java 使用Netty构建只有少量客户端的服务器

Java 使用Netty构建只有少量客户端的服务器,java,multithreading,netty,Java,Multithreading,Netty,我熟悉Netty的基础知识,并使用它构建了一个典型的运行在TCP上的应用服务器,该服务器旨在为许多客户机/连接提供服务。然而,我最近有一个需求,即构建一个服务器,该服务器设计用于处理少数客户机,或者大多数情况下仅处理一个客户机。但是,客户端是许多设备的网关,因此会为我试图设计的服务器生成大量流量 我的问题是: 是否有可能/建议在此用例中使用Netty?我已经看到了讨论 是否可以将多线程EventExecutor用于管道中的通道处理程序,以便由EventExecutor线程池实现并发而不是通道E

我熟悉Netty的基础知识,并使用它构建了一个典型的运行在TCP上的应用服务器,该服务器旨在为许多客户机/连接提供服务。然而,我最近有一个需求,即构建一个服务器,该服务器设计用于处理少数客户机,或者大多数情况下仅处理一个客户机。但是,客户端是许多设备的网关,因此会为我试图设计的服务器生成大量流量

我的问题是:

  • 是否有可能/建议在此用例中使用
    Netty
    ?我已经看到了讨论

  • 是否可以将多线程EventExecutor用于管道中的通道处理程序,以便由EventExecutor线程池实现并发而不是通道EventLoop?它会确保来自客户端的一条消息由一个线程通过所有处理程序处理,而下一条消息由另一个线程处理吗

  • 是否有可用的示例实现

根据io.netty.channel.oio的定义如果你没有很多客户,你可以使用它。在这种情况下,每个连接都将在一个单独的线程中处理,并在后台使用Java旧的阻塞IO。查看
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);
            }
        });
    }
}