Сервер Java Netty работает очень медленно, как можно повысить его производительность? ⇐ JAVA
Сервер Java Netty работает очень медленно, как можно повысить его производительность?
Я написал 2 простых сервера, один с Netty, а другой с сокетом Java-сервера и многопоточностью. Я хочу использовать Netty для моего реального сервера, чтобы обрабатывать большое количество соединений и пересылать их в некоторые пункты назначения. Но он очень медленно выполняет ввод-вывод! это мой серверный код с ServerSocket:
публичный класс TargetServer { данные частного статического байта [] = новый байт [1024*1024*1000]; public static void main(String[] args) { Служба ExecutorService = Executors.newCachedThreadPool(); попробуйте (ServerSocket serverSocket = новый ServerSocket (2525)) { пока (правда){ Сокет сокета = serverSocket.accept(); System.out.println("принято"); System.out.println("количество потоков = "+Thread.activeCount()); service.execute(новый SocketWriter(сокет)); } } catch (IOException e) { е.printStackTrace(); } } частный статический класс SocketWriter реализует Runnable{ частный сокет mSocket; частный SocketWriter (сокет сокета) { мсокет = сокет; } @Override общественный недействительный запуск () { попробуйте (OutputStream outputStream = mSocket.getOutputStream()) { ByteArrayInputStream in = новый ByteArrayInputStream (данные); интервал Лен; байт[] бафф = новый байт[4086]; while ((len = in.read(buff)) != -1){ outputStream.write(buff,0,len); выходной поток.flush(); } System.out.println("все отправлено"); } catch (IOException e) { е.printStackTrace(); } } } } А это код моего сервера Netty:
публичный класс NettyServer { общественная статическая EventLoopGroup BossGroup = новая NioEventLoopGroup (1); общественная статическая EventLoopGroup workerGroup = новая NioEventLoopGroup (); public static void main(String[] args) { пытаться { ServerBootstrap serverBootstrap = новый ServerBootstrap(); serverBootstrap.group(bossGroup,workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer() { @Override protected void initChannel(@NotNull Channel ch) выдает исключение { Конвейер ChannelPipeline = ch.pipeline(); конвейер.addLast(новый NettyForwarder("127.0.0.1",2525)); } }) .childOption(ChannelOption.TCP_NODELAY,истина) ; ChannelFuture cf = serverBootstrap.bind(3000).sync(); System.out.println("Сервер Netty запущен."); cf.channel().closeFuture().sync(); } catch (InterruptedException e) { BossGroup.shutdownИзящно(); BossGroup.shutdownИзящно(); } } } это код NettyForwarder:
@ChannelHandler.Sharable общественный класс NettyForwarder расширяет ChannelInboundHandlerAdapter { частная строка targetHost; частный int targetPort; частный канал outboundChannel; частный финальный Bootstrap mBootstrap; public NettyForwarder (String targetHost, int targetPort) { this.targetHost = targetHost; this.targetPort = целевой порт; mBootstrap = новый Bootstrap(); } @Override public void ChannelActive(@NotNull ChannelHandlerContext ctx) выдает исключение { Канал inboundChannel = ctx.channel(); mBootstrap.group(ctx.channel().eventLoop()) .channel(inboundChannel.getClass()) .handler(новый TargetHandler(inboundChannel)) .option(ChannelOption.TCP_NODELAY,истина) .option(ChannelOption.SO_KEEPALIVE,истина) .option(ChannelOption.AUTO_READ,истина) ; ChannelFuture f = mBootstrap.connect(targetHost,targetPort); исходящийканал = f.channel(); } @Override public void ChannelRead(@NotNull ChannelHandlerContext ctx, @NotNull Object msg) выдает исключение { ByteBuf msgBuf = (ByteBuf) msg; sendToOutbound (ctx, msgBuf); } частная пустота sendToOutbound (ChannelHandlerContext inContext, БайтБуф сообщение) { если (outboundChannel.isActive()){ outboundChannel.writeAndFlush(msg).addListener(new ChannelFutureListener() { @Override public void OperationComplete(ChannelFuture ChannelFuture) выдает исключение { если (!channelFuture.isSuccess()){ каналFuture.cause().printStackTrace(); closOnFlush(inContext.channel()); }еще { inContext.read(); } } }); }еще { ReferenceCountUtil.safeRelease(msg); closOnFlush(inContext.channel()); } } @Override public voidchannelInactive(ChannelHandlerContext ctx) выдает исключение { super.channelInactive(ctx); ClosOnFlush (исходящий канал); } @Override public voidExceptionCaught(ChannelHandlerContext ctx, Throwable Cause) выдает исключение { причина.printStackTrace(); ClosOnFlush (исходящий канал); closOnFlush(ctx.channel()); } частный недействительный closOnFlush (Канал c) { if (c != null && c.isOpen()){ c.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); } } } Я использую этот клиентский код для тестирования обоих серверов:
публичный класс SourceClient { public static void main(String[] args) { пытаться { число интервалов = 5; Служба ExecutorService = Executors.newFixedThreadPool(count); for (int i = 0; i < count; i++) { Сокет сокет = новый сокет("127.0.0.1",3000); System.out.println("подключено"); service.execute(новый SocketReader(socket, i)); } сервис.выключение(); } catch (Исключение е) { е.printStackTrace(); } } частный статический класс SocketReader реализует Runnable{ частный сокет mSocket; частный внутренний номер; Private SocketReader (сокет сокета, номер int) { мсокет = сокет; этот.номер = номер; } @Override общественный недействительный запуск () { попробуйте (InputStream inputStream = mSocket.getInputStream()) { байт[] бафф = новый байт[2048]; интервал Лен; long initTime = Calendar.getInstance().getTimeInMillis(); длинный startTime = initTime; двойной allBytesRead = 0; длинный currenTime = initTime; while ((len = inputStream.read(buff)) != -1){ allBytesRead += Лен; currenTime = Calendar.getInstance().getTimeInMillis(); если (currenTime - startTime >= 1000){ System.out.println("скорость "+number+" : "+allBytesRead/1024d/1024d+" МБ/с"); startTime = текущее время; allBytesRead = 0; } } System.out.println("все время получения: "+(currenTime - initTime)/1000); } catch (IOException e) { е.printStackTrace(); } } } } Когда я запускаю SourceClient с портом 3000, средняя скорость загрузки составляет около 60 МБ/с, а время завершения — около 21 секунды для каждого соединения. Но когда я запускаю SourceClient с портом 2525, который напрямую подключается к TargetServer, средняя скорость загрузки результата составляет около 120 МБ/с, а время завершения составляет около 9 секунд для каждого соединения! как улучшить производительность netty? Или мне не следует использовать Java для моего реального сервера?
Я написал 2 простых сервера, один с Netty, а другой с сокетом Java-сервера и многопоточностью. Я хочу использовать Netty для моего реального сервера, чтобы обрабатывать большое количество соединений и пересылать их в некоторые пункты назначения. Но он очень медленно выполняет ввод-вывод! это мой серверный код с ServerSocket:
публичный класс TargetServer { данные частного статического байта [] = новый байт [1024*1024*1000]; public static void main(String[] args) { Служба ExecutorService = Executors.newCachedThreadPool(); попробуйте (ServerSocket serverSocket = новый ServerSocket (2525)) { пока (правда){ Сокет сокета = serverSocket.accept(); System.out.println("принято"); System.out.println("количество потоков = "+Thread.activeCount()); service.execute(новый SocketWriter(сокет)); } } catch (IOException e) { е.printStackTrace(); } } частный статический класс SocketWriter реализует Runnable{ частный сокет mSocket; частный SocketWriter (сокет сокета) { мсокет = сокет; } @Override общественный недействительный запуск () { попробуйте (OutputStream outputStream = mSocket.getOutputStream()) { ByteArrayInputStream in = новый ByteArrayInputStream (данные); интервал Лен; байт[] бафф = новый байт[4086]; while ((len = in.read(buff)) != -1){ outputStream.write(buff,0,len); выходной поток.flush(); } System.out.println("все отправлено"); } catch (IOException e) { е.printStackTrace(); } } } } А это код моего сервера Netty:
публичный класс NettyServer { общественная статическая EventLoopGroup BossGroup = новая NioEventLoopGroup (1); общественная статическая EventLoopGroup workerGroup = новая NioEventLoopGroup (); public static void main(String[] args) { пытаться { ServerBootstrap serverBootstrap = новый ServerBootstrap(); serverBootstrap.group(bossGroup,workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer() { @Override protected void initChannel(@NotNull Channel ch) выдает исключение { Конвейер ChannelPipeline = ch.pipeline(); конвейер.addLast(новый NettyForwarder("127.0.0.1",2525)); } }) .childOption(ChannelOption.TCP_NODELAY,истина) ; ChannelFuture cf = serverBootstrap.bind(3000).sync(); System.out.println("Сервер Netty запущен."); cf.channel().closeFuture().sync(); } catch (InterruptedException e) { BossGroup.shutdownИзящно(); BossGroup.shutdownИзящно(); } } } это код NettyForwarder:
@ChannelHandler.Sharable общественный класс NettyForwarder расширяет ChannelInboundHandlerAdapter { частная строка targetHost; частный int targetPort; частный канал outboundChannel; частный финальный Bootstrap mBootstrap; public NettyForwarder (String targetHost, int targetPort) { this.targetHost = targetHost; this.targetPort = целевой порт; mBootstrap = новый Bootstrap(); } @Override public void ChannelActive(@NotNull ChannelHandlerContext ctx) выдает исключение { Канал inboundChannel = ctx.channel(); mBootstrap.group(ctx.channel().eventLoop()) .channel(inboundChannel.getClass()) .handler(новый TargetHandler(inboundChannel)) .option(ChannelOption.TCP_NODELAY,истина) .option(ChannelOption.SO_KEEPALIVE,истина) .option(ChannelOption.AUTO_READ,истина) ; ChannelFuture f = mBootstrap.connect(targetHost,targetPort); исходящийканал = f.channel(); } @Override public void ChannelRead(@NotNull ChannelHandlerContext ctx, @NotNull Object msg) выдает исключение { ByteBuf msgBuf = (ByteBuf) msg; sendToOutbound (ctx, msgBuf); } частная пустота sendToOutbound (ChannelHandlerContext inContext, БайтБуф сообщение) { если (outboundChannel.isActive()){ outboundChannel.writeAndFlush(msg).addListener(new ChannelFutureListener() { @Override public void OperationComplete(ChannelFuture ChannelFuture) выдает исключение { если (!channelFuture.isSuccess()){ каналFuture.cause().printStackTrace(); closOnFlush(inContext.channel()); }еще { inContext.read(); } } }); }еще { ReferenceCountUtil.safeRelease(msg); closOnFlush(inContext.channel()); } } @Override public voidchannelInactive(ChannelHandlerContext ctx) выдает исключение { super.channelInactive(ctx); ClosOnFlush (исходящий канал); } @Override public voidExceptionCaught(ChannelHandlerContext ctx, Throwable Cause) выдает исключение { причина.printStackTrace(); ClosOnFlush (исходящий канал); closOnFlush(ctx.channel()); } частный недействительный closOnFlush (Канал c) { if (c != null && c.isOpen()){ c.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); } } } Я использую этот клиентский код для тестирования обоих серверов:
публичный класс SourceClient { public static void main(String[] args) { пытаться { число интервалов = 5; Служба ExecutorService = Executors.newFixedThreadPool(count); for (int i = 0; i < count; i++) { Сокет сокет = новый сокет("127.0.0.1",3000); System.out.println("подключено"); service.execute(новый SocketReader(socket, i)); } сервис.выключение(); } catch (Исключение е) { е.printStackTrace(); } } частный статический класс SocketReader реализует Runnable{ частный сокет mSocket; частный внутренний номер; Private SocketReader (сокет сокета, номер int) { мсокет = сокет; этот.номер = номер; } @Override общественный недействительный запуск () { попробуйте (InputStream inputStream = mSocket.getInputStream()) { байт[] бафф = новый байт[2048]; интервал Лен; long initTime = Calendar.getInstance().getTimeInMillis(); длинный startTime = initTime; двойной allBytesRead = 0; длинный currenTime = initTime; while ((len = inputStream.read(buff)) != -1){ allBytesRead += Лен; currenTime = Calendar.getInstance().getTimeInMillis(); если (currenTime - startTime >= 1000){ System.out.println("скорость "+number+" : "+allBytesRead/1024d/1024d+" МБ/с"); startTime = текущее время; allBytesRead = 0; } } System.out.println("все время получения: "+(currenTime - initTime)/1000); } catch (IOException e) { е.printStackTrace(); } } } } Когда я запускаю SourceClient с портом 3000, средняя скорость загрузки составляет около 60 МБ/с, а время завершения — около 21 секунды для каждого соединения. Но когда я запускаю SourceClient с портом 2525, который напрямую подключается к TargetServer, средняя скорость загрузки результата составляет около 120 МБ/с, а время завершения составляет около 9 секунд для каждого соединения! как улучшить производительность netty? Или мне не следует использовать Java для моего реального сервера?
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Мой сервер Java Netty работает очень медленно. Как можно повысить его производительность?
Anonymous » » в форуме JAVA - 0 Ответы
- 31 Просмотры
-
Последнее сообщение Anonymous
-