美文网首页netty
Netty源码之NIO

Netty源码之NIO

作者: loveFXX | 来源:发表于2020-04-13 22:48 被阅读0次

    netty是什么

    Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。简单说就是网络编程框架,编写服务端和客户端进行通信

    Netty应用

    Netty作为一个异步高性能通信框架,在远程服务调用的高性能RPC框架中的通信框架
    阿里分布式服务框架 Dubbo(默认使用Netty 作为基础通信组件)
    RocketMQ的消息生产者和消息消费者之间也是使用的netty
    游戏行业网络通信
    在具体了解netty如何使用之前,需要了解BIO、NIO、AIO的基本概念和原理及它们的区别。为什么Netty会选择NIO模型而放弃使用AIO。

    同步和异步,阻塞和非阻塞

    同步和异步是体现在服务提供者(服务端),当调用者调用服务提供的方法,服务提供者能立即返回,并在处理完之后能够返回(可以通过回调方法),那就是异步。如果是等处理完之后再返回,或需要调用者再次查询是否完成则是同步。
    阻塞和非阻塞体现在调用者(客户端),当调用者调用服务提供者的方法,一直等待结果,那就是阻塞。立即返回则是非阻塞。

    BIO、NIO和AIO

    BIO

    同步阻塞I/O模式

    image.png
    BIO通信模型的服务端,由一个 Acceptor 线程负责监听客户端的连接。我们一般通过在while(true) 循环中调用 accept() 方法监听等待接收客户端的连接,一旦接收到一个连接请求,就可以建立通信套接字在这个通信套接字上进行读写操作,此时不能再接收其他客户端连接请求,只能等待同当前连接的客户端的操作执行完成, 可以通过多线程来支持多个客户端的连接。所以,数据的读写在一个线程内完成,如果需要增加并发访问量则需要创建线程。线程的
    不断创建和销毁非常浪费性能
    BIO测试案例
    启动后,浏览器访问返回当前时间

    伪异步 IO

    为了解决并发访问量的线程创建问题出现的


    image.png

    伪异步I/O通信框架采用了线程池实现,避免了线程资源耗尽问题,因为它的底层仍然是BIO模型,因此无法从根本上解决问题

    NIO (New I/O)

    NIO是一种同步非阻塞的I/O模型。在java.nio包中,拥有3个核心概念:Selector(选择器),channel(通道),buffer(缓冲区)。
    java.nio包和java.io包比较:
    java.nio包中,是面向块(block)或是缓冲区(buffer)编程的。
    而java.io包中最为核心的概念是流(stream),是面向流编程的,一个流要么是输入流,要么是输出流。

    NIO组件的关系
    image.png
    每一个channel(通道)都注册到selector(选择器)上,channel数据的读取和写入都是面向Buffer(缓冲区)
    Nio服务端和客户端测试案例
    测试方式及效果:客户端连接后,就可以与服务端交替得到另一端信息。先客户端输入,再服务端输入,一直这样交替下去。
    流程:当服务端启动时,把serverSocketChannel对象注册到selector中,接受可连接事件。当客户端连接到服务端,在while死循环内获取到连接事件,并得到当前连接的SocketChannel对象,并注册到selector,设置事件是OP_READ可读事件。在客户端发送一串输入,在服务端的while死循环内走到isReadable读事件。读取到客户端输入数据,设置OP_WRITE可写事件,然后服务端键盘输入,客户端获取,再次变为可读事件。

    AIO(Asynchronous I/O)

    异步非阻塞的IO模型,异步 IO 是基于事件和回调机制实现的,应用操作之后会直接返回,不会堵塞在那里。

    Netty为什么去掉支持AIO

    https://github.com/netty/netty/issues/2515
    1、在linux系统上,AIO的底层实现是epoll。并不比NIO快
    2、Netty是reactor模型, 而AIO是proactor模型
    3、AIO需要预先分配缓存,NIO按需分配

    Reactor模型

    Doug Lea大神文档
    在了解NIO的基本使用及概念后,需要了解NIO在Reactor模式的应用。

    1、单Reactor单线程模式
    Reactor单.png
    单Reactor单线程测试案例
    实现原理是:Reactor线程监控是否有新的事件,对于不同的事件dispatch转发到不同的处理模块。acceptor处理客户端连接事件,连接后获取SocketChannel通道并注册可读事件。在Reactor线程内检测到有新事件,则会转发到相应的事件(可读或可写事件)。对于这种实现方式,如果decode(解码)、compute(计算)、encode(编码)非常耗的资源,则客户端调用则会阻塞。所以出现了对这部分的多线程处理,叫单Reactor多线程模型。
    2、单Reactor多线程模型
    单Reactor多.png
    单Reactor多工作线程测试案例
    相对于第一种,就是处理业务逻辑部分由线程池处理。这样可以减小reactor的性能开销,从而更专注的做事件分发dispatch工作了,从而提升整个应用的吞吐量。
    缺点:连接和读写事件都是由一个Reactor进行处理
    3、多Reactor多线程模型
    MultipleReactor.png
    多Reactor线程模式测试案例
    实现原理:mainReactor负责处理新连接的建立(需要一个线程就可以),然后把连接后获得的socketChannel通道注册到subReactor。对于读写网络数据,对业务处理等功能,交给worker线程池来处理。这种模式耦合度更低,性能和稳定性也有所提升。在这种模式下的应用有mina 和netty。

    总结:

    1、需要了解BIO、NIO、AIO的基本概念及其原理
    2、NIO所涉及的类及其关系
    3、Reactor三种模型
    4、为什么Netty会选择NIO

    相关文章

      网友评论

        本文标题:Netty源码之NIO

        本文链接:https://www.haomeiwen.com/subject/srcnmhtx.html