Netty和传统NIO之间的比较

这篇具有很好参考价值的文章主要介绍了Netty和传统NIO之间的比较。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  1. Netty回显服务器实现:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class NettyEchoServer {

    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline().addLast(new EchoServerHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            serverBootstrap.bind(8080).sync().channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    private static class EchoServerHandler extends SimpleChannelInboundHandler<String> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String msg) {
            System.out.println("Received message: " + msg);
            ctx.writeAndFlush(msg);
        }
    }
}

上述代码是一个使用Netty实现的回显服务器。让我们逐行解释代码的实现:

  • 首先,我们创建了两个NioEventLoopGroup,一个用于接收客户端连接(bossGroup),另一个用于处理客户端连接上的请求(workerGroup)。
  • 然后,我们创建一个ServerBootstrap实例,并配置各种参数,如所使用的通道类型、事件处理器等。
  • childHandler()方法中,我们初始化处理器链,这里只有一个EchoServerHandler处理器。
  • EchoServerHandler是一个继承自SimpleChannelInboundHandler的处理器,它处理接收到的消息并将其回显给客户端。
  • 接下来,我们绑定服务器端口并启动服务器。
  • 最后,我们关闭并释放资源。
  1. 传统NIO回显服务器实现:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class TraditionalNioEchoServer {

    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(8080));
        serverSocketChannel.configureBlocking(false);

        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            selector.select();
            Set<SelectionKey> selectedKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectedKeys.iterator();

            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                iterator.remove();

                if (key.isAcceptable()) {
                    ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
                    SocketChannel socketChannel = serverChannel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                } else if (key.isReadable()) {
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int bytesRead = socketChannel.read(buffer);
                    if (bytesRead == -1) {
                        socketChannel.close();
                        continue;
                    }
                    buffer.flip();
                    String message = new String(buffer.array(), 0, bytesRead);
                    System.out.println("Received message: " + message);

                    socketChannel.write(buffer);
                    key.interestOps(SelectionKey.OP_READ);
                }
            }
        }
    }
}

上述代码是一个使用传统NIO实现的回显服务器。让我们逐行解释代码的实现:

  • 首先,我们创建一个ServerSocketChannel实例,并将其绑定到指定的端口上。
  • 然后,我们配置ServerSocketChannel为非阻塞模式,并创建一个Selector实例。
  • Selector上注册ServerSocketChannel,并将其设置为接受连接的操作。
  • 进入主循环,调用selector.select()等待就绪的事件。
  • 一旦有事件就绪,我们获取就绪的SelectionKey集合,并遍历处理每个就绪的SelectionKey
  • 如果SelectionKey是可接受的,我们接受客户端连接,并将客户端SocketChannel注册到Selector上,并设置为可读操作。
  • 如果SelectionKey是可读的,我们读取客户端发送的数据,并将其回显给客户端。
  • 最后,我们继续循环处理就绪的事件。

- 其他特性

当涉及到Netty的高级抽象和扩展性时,它们如何帮助开发网络应用程序主要体现在以下几个方面:

  1. 高级抽象:Netty提供了一组高级抽象,如ChannelHandlerChannelPipelineByteBuf等,它们封装了底层的网络操作和数据处理,简化了开发过程。这些高级抽象使开发人员能够专注于业务逻辑而不必过多关注网络操作的细节。例如,通过使用ChannelHandlerChannelPipeline,开发人员可以轻松地定义事件处理器链,处理不同类型的事件,以及对数据进行编解码等操作。这种高级抽象使得编写网络应用程序变得更加简洁和可读。

下面是一个使用Netty高级抽象的简单示例,它演示了一个回显服务器:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class NettyEchoServer {

    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline().addLast(new EchoServerHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            serverBootstrap.bind(8080).sync().channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    private static class EchoServerHandler extends SimpleChannelInboundHandler<String> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String msg) {
            System.out.println("Received message: " + msg);
            ctx.writeAndFlush(msg);
        }
    }
}

在上述代码中,我们使用了Netty的高级抽象和组件:

  • ServerBootstrap:它是Netty启动服务器的入口,它封装了服务器的配置和启动过程。
  • ChannelInitializer:它是用于初始化新的连接的Channel的处理器。我们可以在其中添加我们自定义的处理器。
  • ChannelOption:它是用于配置ServerBootstrap的选项,例如设置TCP的参数。
  • SimpleChannelInboundHandler:它是一个抽象类,提供了一些方便的方法来处理不同类型的事件,比如channelRead0()方法用于处理接收到的消息。

通过使用这些高级抽象,我们可以轻松地定义和配置服务器,并实现业务逻辑的处理。

  1. 扩展性:Netty具有良好的可扩展性,允许开发人员自定义和添加自己的处理器和组件。Netty的设计使得添加新的功能或修改现有功能变得相对简单。

以下是一个示例,展示了如何自定义一个处理器来处理特定的业务需求:

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class CustomHandler extends SimpleChannelInboundHandler<String> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        // 自定义业务逻辑处理
        // ...
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // 异常处理
        // ...
    }
}

在上述代码中,我们创建了一个自定义处理器CustomHandler,继承自SimpleChannelInboundHandler。通过重写channelRead0()方法,我们可以自定义处理接收到的消息的逻辑。通过使用Netty的高级抽象和扩展性,开发人员可以更轻松地构建和扩展网络应用程序。高级抽象简化了网络操作和数据处理的编程模型,使开发人员能够专注于业务逻辑而不必处理底层细节。同时,Netty的扩展性允许开发人员根据自己的需求添加自定义的处理器和组件,以实现特定的功能和逻辑。这种灵活性使得Netty成为一个强大且受欢迎的框架,用于构建高性能的网络应用程序。


还有一些方面需要考虑:

  1. 异步和事件驱动:Netty是基于事件驱动和异步的I/O模型。它使用了NIO(Non-blocking I/O)机制,使得应用程序能够处理大量的并发连接而不会阻塞。Netty将I/O操作转化为事件,并通过回调机制通知应用程序处理这些事件。这种异步和事件驱动的特性使得Netty非常适合构建高性能、可扩展的网络应用程序,能够处理大量的并发连接和高负载。

  2. 高性能和可伸缩性:Netty通过优化底层网络操作和数据处理,提供了高性能和可伸缩性。它使用了一些技术,如零拷贝(zero-copy)和内存池(memory pooling),以减少数据复制和内存分配的开销。Netty还使用了多线程和线程池来处理并发连接和请求,并通过事件循环(Event Loop)机制来实现高效的事件处理。这些优化措施使得Netty能够处理大规模的并发连接,并具有出色的性能表现。

  3. 多协议支持:Netty支持多种常见的网络协议,如TCP、UDP、HTTP、WebSocket等。它提供了一组相应的高级抽象和组件,使得开发人员能够轻松地构建基于这些协议的应用程序。Netty的高级抽象和扩展性使得开发人员能够自定义和扩展协议的处理逻辑,以满足特定的需求。

总之,Netty的高级抽象和扩展性使得开发人员能够以简洁、灵活和高效的方式构建网络应用程序。它提供了丰富的工具和组件,简化了网络编程的复杂性,同时提供了优异的性能和可伸缩性。无论是构建高性能服务器、实时通信应用还是分布式系统,Netty都是一个强大而可靠的选择。文章来源地址https://www.toymoban.com/news/detail-793797.html

到了这里,关于Netty和传统NIO之间的比较的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • NIO和netty的常用类

    给ServerBootstrap配置两个EventLoopGroup,一个建立连接,一个处理网络io。 EventLoopGroup给EventLoop分配线程。 在 Netty 中,EventLoop 通过不断轮询 Selector 来检测 Channel 上发生的事件,当 Channel 上的事件到达时,EventLoop 会将事件传入 相应的Channel 的成员变量 ChannelPipeline 中,经过所有C

    2024年01月25日
    浏览(51)
  • Java NIO 和 Netty快速入门

    channel 是读写数据的双向通道,可以从 channel将数据读入buffer,也可以将buffer数据写入channel(较之前的stream要么是输入,要么是输出更为底层) 四种常见Channel: FileChannel DatagramChannel SocketChannel ServerSocketChannel buffer用来缓冲读写数据 常见buffer: ByteBuffer MappedByteBuffer DirectByteBuffer

    2024年02月22日
    浏览(42)
  • Netty-01-快速掌握Java NIO

    Blocking IO也称为BIO,即同步阻塞IO。Java的io包基于流模型实现,提供了File、FileInputStream、FileOutputStream等输⼊输出流的功能。Java的io包下提供的流操作,交互⽅式是同步且阻塞的⽅式,在输⼊输出流的操作进⾏读、写动作完成之前,线程会⼀直 阻塞 。因此io包中对流的操作容易

    2024年02月10日
    浏览(44)
  • 以 Java NIO 的角度理解 Netty

    上篇文章《Netty 入门指南》主要涵盖了 Netty 的入门知识,包括 Netty 的发展历程、核心功能与组件,并且通过实例演示了如何使用 Netty 构建一个 HTTP 服务器。由于 Netty 的抽象程度较高,因此理解起来可能会更加复杂和具有挑战性,所以本文将通过 Java NIO 的处理流程与 Netty 的

    2024年02月12日
    浏览(44)
  • netty(二):NIO——处理可写事件

    在服务端一次性无法把数据发送完的情况下,需要注册可写事件 服务端一次性是否能够把数据全部发送完成取决于服务端的缓冲区大小,该缓冲区不受程序控制 判断ByteBuffer是否仍有剩余,如果有剩余注册可写事件 监听可写事件,判断数据是否写完,数据写完需要 客户端 服

    2024年02月11日
    浏览(47)
  • Netty Review - NIO空轮询及Netty的解决方案源码分析

    Netty Review - ServerBootstrap源码解析 Netty Review - NioServerSocketChannel源码分析 Netty Review - 服务端channel注册流程源码解析 NIO空轮询(Empty Polling)是指在使用Java NIO 时,当Selector上注册的Channel没有就绪事件时,Selector.select()方法会返回0,但该方法会导致CPU空转,因为它会不断地调用操

    2024年02月21日
    浏览(52)
  • 使用nio代替传统流实现文件上传和下载功能

    1.文件下载 2.文件上传

    2024年02月13日
    浏览(42)
  • Java NIO 图解 Netty 服务端启动的过程

    了解整体Netty常用的核心组件后,并且对比了传统IO模式。在对比过程中,找到了传统IO对应Netty中是如何实现的。最后我们了解到在netty中常用的那些组件。 本文在了解下这些核心组件的前提下,进一步了解组件如何在整个服务器启动过程如何被创建,如何组件之间配合来使

    2024年02月11日
    浏览(38)
  • 由浅入深Netty基础知识NIO网络编程

    阻塞模式下,相关方法都会导致线程暂停 ServerSocketChannel.accept 会在没有连接建立时让线程暂停 SocketChannel.read 会在没有数据可读时让线程暂停 阻塞的表现其实就是线程暂停了,暂停期间不会占用 cpu,但线程相当于闲置 单线程下,阻塞方法之间相互影响,几乎不能正常工作,

    2024年02月05日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包