zoukankan      html  css  js  c++  java
  • NIO到Netty

    同步阻塞IO: 用户进程发起IO操作后 等待IO操作完成 用户进程才能运行
    同步非阻塞IO:用户进程发起IO操作后做其他事情,用户进程时不时询问IO操作是否就绪,从而引入不必要CPU资源
    异步阻塞IO:指应用发起一个IO操作后 不等待内核IO操作完成,内核完成IO操作后会通知应用程序
    同步和异步的区别:同步必须等待或主动询问IO是否完成 而异步不会

    同步I/O中select,poll,epoll都需要在读写事件就绪后自己负责进行读写,这个读写过程是阻塞的 (Selector.select()阻塞可以监听多个句柄 在NIO中实际上是一条线程拥有很多的IO,有任何一个IO有数据 ,selector就被唤醒)

    异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间

    NIO是Java中的一种同步非阻塞IO,NIO是面向buffer的非阻塞IO
    通过selector(Selector用于监听多个Channel的),
    Channel(读取或者写入数据,对Channel的读写必须通过buffer对象),
    buffer(存放待读写数据的容器) 实现非阻塞io操作,用到了反应器设计模式(react)

    nio多路复用的原理
    使用NIO的服务端内部有一个多路轮询器selector,用于监听端口,当客户端尝试连接时,selector就会收到通知,但并不会直接创建一个线程来建立连接,而是交给内核去处理,当客户端把数据都传送过来,进入nio的缓存中时,服务端才会创建一个线程,通过一个Channel去接受数据。
    只有当数据准备好所有资源,请求IO时,才会开启一个新的线程
    Reactor模型中主要有三种角色:
    Reactor:内部封装了一个selector,循环调用select方法获得就绪channel。然后将就绪channel dispatch给对应handler执行真的读写逻辑
    Acceptor:监听客户端连接,并为客户端的SocketChannel向Reactor注册对应的handler
    Handlers:真正执行非阻塞读/写任务逻辑

    nio多路复用I/O模型利用select、poll、epoll可以同时监视多个流的I/O事件,在空闲时,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就会从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll只轮询哪些真正发出了事件的流),并且只依次顺序处理就绪的流,这种做法就避免了大量的无用操作

    由于JDK的selector在linux等操作系统上时通过epoll实现,它没有连接句柄数的限制,所以selector线程可以同时处理成千上万个客户端连接,且性能不会下降

    Netty是完全基于NIO实现的 对TCP、UDP和文件传输协议的支持
    Netty的架构类似于多Reactor多线程模型,但是Netty默认不使用Worker线程池执行Handler,而是直接使用IO线程执行读写任务
    Netty避免线程切换,Netty在很多地方进行了无锁化设计,通过调整NIO线程池的线程参数,可以同时启动多个串行化的线程并行运行

    零拷贝
    传统的BIO模式(同步阻塞) 数据从磁盘–》内核的read buffer–》用户缓冲区–》内核的socket buffer–》网卡接口的缓冲区
    IO流程包含两次用户态和内核态上下文切换,在高并发场景下,这些会很繁杂。
    因此,Linux提出了零拷贝的概念:即避免用户态和内核态的切换,直接在内核中进行数据传递。
    Linux提供了两个函数mmap和sendfile来实现零拷贝
    mmap: 内存映射文件,即将文件的一段直接映射到内存,内核和应用进程共用同一块内存地址
    sendfile: 从内核缓冲区直接复制到socket缓冲区, 不需要向应用进程缓冲区拷贝

    NIO非阻塞Linux sendfile()实现
    操作系统内核中,数据由read buffer->socket buffer

    netty层面:指避免数据在用户态中冗余拷贝,提高数据的传输速率
    Netty的接收和发送ByteBuffer采用DIRECT BUFFERS,使用堆外直接内存进行Socket读写 //无需多次拷贝
    Netty: 调用transferTo,数据从文件由DMA引擎–》内核read buffer-》网卡接口buffer

    netty设计模式
    责任链模式:将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止

    netty中handler的执行顺序
    channelInboundHandler按照注册的先后顺序执行
    channelOutboundHandler按照注册的先后顺序逆序执行

    群交流(262200309)
  • 相关阅读:
    runtime关联属性示例
    Loader之二:CursorLoader基本实例
    Loader之一:基本原理
    Fragment之三:根据屏幕尺寸加载不同的Fragment
    Fragment之一:Fragment入门
    Github android客户端源代码分析之一:环境搭建
    如何在Eclipse中查看Android API源码以及support包源码
    Intent七在属性之一:ComponentName
    Intent七大属性之总结
    使用SQLiteHelper创建数据库并插入数据
  • 原文地址:https://www.cnblogs.com/webster1/p/13157639.html
Copyright © 2011-2022 走看看