网络性能缓慢



我正在使用netty从服务器下载大文件。在使用 jmeter 运行性能测试时,我发现我的服务器在 150 个并发用户之前提供了非常高的吞吐量,但是一旦并发用户数量增加,它就会开始下降,几乎变成了 500 个并发用户的一半。

网络服务器 -

ServerBootstrap b = new ServerBootstrap();
    EpollEventLoopGroup bossGroup = new EpollEventLoopGroup();
    EpollEventLoopGroup workerGroup = new EpollEventLoopGroup();
  try {
        b.group(bossGroup, workerGroup).channel(EpollServerSocketChannel.class).handler(new LoggingHandler(LogLevel.DEBUG)).childHandler(new FileServerInitializer());
        Channel ch = b.bind(port).sync().channel();
        ch.closeFuture().sync();
    } finally {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
        FileServerHandler.threadPool.shutdownNow();
    }

文件服务器初始值设定项 -

ChannelPipeline pipeline = ch.pipeline();
    pipeline.addLast("decoder", new HttpRequestDecoder());
    pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
    pipeline.addLast("encoder", new HttpResponseEncoder());
    pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());
    pipeline.addLast("handler", (ChannelHandler) new FileServerHandler());
}

文件服务器处理程序 -

    RandomAccessFile raf;
    try {
        raf = new RandomAccessFile(file, "r");
    } catch (FileNotFoundException ignore) {
        sendError(ctx, HttpResponseStatus.NOT_FOUND);
        return;
    }
    response = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.OK);
    response.headers().set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileNameType);
    response.headers().set(HttpHeaders.CONTENT_LENGTH, String.valueOf(size));
    ctx.write(response);
    ChannelFuture sendFileFuture;
    ChannelFuture lastContentFuture;
    sendFileFuture = ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, size, 8192)),ctx.newProgressivePromise());
    lastContentFuture = sendFileFuture; 
    sendFileFuture.addListener(new ChannelProgressiveFutureListener() {
        public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) {
            if (total < 0) {            
                System.out.println(future.channel() + " Transfer progress: " + progress);
            }else {
                System.out.println(future.channel() + " Transfer progress: " + progress + " / " + total);
            }
        }
        public void operationComplete(ChannelProgressiveFuture future) {
            System.out.println(future.channel() + " Transfer complete.");
        }
    });
    lastContentFuture.addListener(ChannelFutureListener.CLOSE);

谁能告诉我为什么会这样?

您也可以尝试:

  1. 例如,更改网络端的子属性(获取自己的正确值)

    bootstrap.channel(NioServerSocketChannel.class);
    bootstrap.group(groupBoss, groupWorker);
    bootstrap.option(ChannelOption.TCP_NODELAY, true);
    bootstrap.option(ChannelOption.SO_REUSEADDR, true);
    bootstrap.option(ChannelOption.SO_LINGER, 0);
    bootstrap.childOption(ChannelOption.TCP_NODELAY, true);
    bootstrap.childOption(ChannelOption.SO_REUSEADDR, true);
    bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
    bootstrap.childOption(ChannelOption.SO_LINGER, 0);
    bootstrap.childOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, timeout);
    bootstrap.childOption(ChannelOption.SO_RCVBUF, 1048576);
    bootstrap.childOption(ChannelOption.SO_SNDBUF, 1048576);
    bootstrap.childOption(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 10*65536);
    bootstrap.childOption(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 2*65536);
    bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
    
  2. 调整 BOSS 和 WORKER 端的线程数(默认值为 2N+1,如果我没记错的话,N 是 Boss 的核心数字)

    我通常为 Boss 设置 2N+1,为 Worker 设置 10N+1(将 Worker 视为异步工作线程,这意味着这不是对并发客户端的真正限制,而只是在"真正的"并发客户端上,这意味着它们实际上做了一些事情)。在 Linux 上要小心,以相应地增加文件描述符限制。

  3. 更精确地指定工作线程级别

当然,也可以看到其他建议

最新更新