【问题标题】:Config the server uses netty 4 has 20,000 client's connection配置服务器使用netty 4有20,000个客户端的连接
【发布时间】:2015-11-05 03:22:37
【问题描述】:

我正在使用netty 4.0编写TCP服务器,可能同时有20k客户端负载。但我的服务器无法承受许多这样的连接。 这是我的代码。

private void initServer(){
EventLoopGroup boosGroup = new NioEventLoopGroup(100);
EventLoopGroup workerGroup = new NioEventLoopGroup(1000);
EventExecutorGroup eegHandle = new DefaultEventExecutorGroup(1000);
EventExecutorGroup eegDecode = new DefaultEventExecutorGroup(1000);
EventExecutorGroup eegEndcode = new DefaultEventExecutorGroup(1000);
try {
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(boosGroup, workerGroup);
        bootstrap.channel(NioServerSocketChannel.class);
        bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {

            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ChannelPipeline pipeLine = ch.pipeline();
                //add check idle time of connection
                pipeLine.addLast("Ilde event", new IdleStateHandler(timeIdleRead, timeIdleWrite, 0));
                //add idle handler to handle idle connection
                pipeLine.addLast("Idle handler", new ServerHandleIdleTime(logger));
                //add decode handler to decode message received from client
                pipeLine.addLast(eegDecode, new ServerMsgDecoder());
                //add business handler to process business
                pipeLine.addLast(eegHandle, new ServerHandleSimple());
                //add encode handler to encode message send to client
                pipeLine.addFirst(eegEncode, new ServerMsgEncoder());
            }
        });
        bootstrap.option(ChannelOption.SO_BACKLOG, 200);
        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, false);
        // bootstrap.option(ChannelOption.SO_TIMEOUT, 10000);
        ChannelFuture channelFuture = bootstrap.bind(host, port);
        channelFuture.sync();
        channelFuture.channel().closeFuture().sync();
    } catch (Exception e) {
        logger.error("", e);
    } finally {
        workerGroup.shutdownGracefully();
        boosGroup.shutdownGracefully();
    }}

我应该像这样使用 3 for 3 处理程序 EventExecutorGroup 吗? 我使用 nthread(= 1000) for workerGroup 是否有足够的 20k 连接? 希望大家帮忙重新配置服务器。 谢谢!

【问题讨论】:

    标签: java asynchronous server netty nio


    【解决方案1】:

    NIO 并不意味着拥有与连接的客户端一样多的线程,而是意味着尽可能多的活动客户端(传入或传出消息),至少如果您希望它们是并行的。

    否则,如果不希望最大并行性,那么您将在每条消息之间稍等片刻(每个线程将尽快从一个通道转到另一个通道)。一般来说,这不是问题。

    但是我认为 1000 已经很多了。但这可能真的取决于您的需求。 1000 表示 20K 客户端,意味着同时最多 5% 的客户端真正处于活动状态(即使它们已连接)。如果您的客户端已连接并且真正处于活动状态,则 1000 条可能还不够...如果您的客户端每秒发送 1 条消息,并且每条消息需要 100 毫秒,那么这意味着平均 10% 的并发消息,所以 2000...你得自己想办法。

    在您的EventExecutorGroup 上,这取决于您的编码器和解码器以及业务 处理程序:

    • 如果一个被阻塞或花费很长时间,那么这个可能需要EventExecutorGroup
    • 如果没有,则不需要这样的EventExecutorGroup

    您也可以尝试以下方法:

    • 如有必要,将线程数增加到编解码器和业务处理程序以及 workerGroup 中可能的活动(或并发)消息的数量。
    • 对多个处理程序使用相同的EventExecutorGroup
    • 在您的引导程序中将 ChannelOption.SO_REUSEADDR 添加为 true。
    • bossGroup 通常应达到(2 x 核心数)+1(因此,如果您有 6 个核心,则可以将其设置为 13)。应该没有必要将其增加到 100。
    • 让你的处理程序的顺序更符合惯例:

      1. IdleStateHandler
      2. ServerHandleIdleTime
      3. ServerMsgDecoder
      4. ServerMsgEncoder // 由于 addFirst 而在您的代码中处于首位
      5. ServerHandleSimple

    【讨论】:

    • 如果对您有帮助,请验证答案,以便下一个读者可以关注它。 ;-)
    • 感谢您的回复。我的客户每 10 秒向服务器发送一条消息。有时可能会更短。我已将 workerGroup 配置为 2000 个线程。 Put EventExecutorGroup 有 3000 个线程用于编码器和解码器以及业务处理程序。设置 ChannelOption.SO_REUSEADDR 为真。现在我有 10,000 个新连接,但根据我的日志,一些主动客户端关闭了连接(错误:现有连接被远程主机强行关闭)。据我了解,服务器不能满足新的应该会出现这种情况。我还没有找到解决这个问题的方法。
    • @dovuvnd 我相信 workerGroup 和 EventExecutorGroup 可以具有相同的大小(如果我理解,您将 2000 放在第一个,将 3000 放在第二个)。对于您问题的下一部分,我相信这是一个不同的问题,因为与拥有 20K 客户的能力无关。因此,请打开一个包含更多详细信息的新文件并验证该文件。 ;-)
    • 也许我的问题是配置服务器这么有效。您可以分享一些想法和经验作为我的问题,不是吗? ps:我的英文不好。希望你同情
    猜你喜欢
    • 2018-09-29
    • 2019-06-06
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 2017-03-07
    • 1970-01-01
    相关资源
    最近更新 更多