Netty网络编程

参考文档
https://zhuanlan.zhihu.com/p/550956053
https://zhuanlan.zhihu.com/p/514448867

BIO

Netty网络编程_第1张图片
读取数据有两个阶段

  1. 等待数据就绪,数据到达内核缓冲区
  2. 读取数据(系统调用),从内核缓冲区,拷贝至用户缓冲区

BIO两个阶段都会阻塞
BIO编程时,需要为每个创建一个线程,如果没有数据可读,该线程将会阻塞在读数据的方法上,造成线程资源浪费。

Netty网络编程_第2张图片

非阻塞IO

Netty网络编程_第3张图片

多路复用NIO

IO多路复用就是基于FD
文件描述符(FD) :是一个从0 开始的无符号整数,用来关联Linux中的一个文件。在Linux中,一切皆文件,例如常规文件、视频、硬件设备等,当然也包括网络套接字(Socket)。
Netty网络编程_第4张图片
阶段一:
用户进程调用select,指定要监听的FD集合;
内核监听FD对应的多个socket;
任意一个或多个socket数据就绪则返回readable;
此过程中用户进程阻塞
阶段二:
用户进程找到就绪的socket
依次调用recvfrom读取数据
内核将数据拷贝到用户空间
用户进程处理数据

IO多路复用:是利用单个线程来同时监听多个FD,并在某个FD可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。但是监听FD、通知的方式又有以下几种:

  • select(正是上述图中的那种)
    • Linux最早是由的I/O多路复用技术
  • poll
    • poll模式是在select模式的基础上进行的改进,但是只是很简单的改进。
  • epoll
    • 基于epoll实例中的红黑树保存要监听的FD,理论上无上限,而且增删改查效率都非常高
    • 每个FD只需要执行一次epoll_ctl添加到红黑树,以后每次epol_wait无需传递任何参数,无需重复拷贝FD到内核空间
    • 利用ep_poll_callback机制来监听FD状态,无需遍历所有FD,因此性能不会随监听的FD数量增多而下降

JAVA-NIO

java1.4 开始支持NIO,但用起来比较复杂。
netty基于java-nio做了封装,简化了很多。直接看netty

Netty

官网例子 https://github.com/netty/netty

Reactor模型

1.Reactor单线程模型

多路复用、事件分发和处理共用一个线程
Netty网络编程_第5张图片

2.Reactor多线程模型

  1. 一个负责处理连接请求的accepter线程
  2. 一组负责读数据/处理数据/写数据的线程池 //TODO 读写和处理是同一组线程吗?

处理过程

  • Reactor对象通过Selector监听客户端请求事件,通过dispatch进行分发;Reactor处理所有事件的监听和响应
  • 如果是连接事件,则由Acceptor通过accept方法处理连接请求,然后创建一个Handler对象响应事件;
  • 如果不是连接请求,则由Reactor对象调用对应handler对象进行处理;handler只响应事件,不做具体的业务处理,它通过read方法读取数据后,会分发给线程池的某个线程进行业务处理,并将处理结果返回给handler;
  • handler收到响应后,通过send方法将结果返回给client。

Netty网络编程_第6张图片

3.主从Reactor多线程模型

  1. MainReactor来处理连接事件,
  2. 非连接事件,分发给SubReactor进行处理
    Netty网络编程_第7张图片

Netty源码解析

//TODO

nio的几个重要组件:Selector(事件选择器),Channel(通信通道),Buffer(通信载体)

netty的几个重要组件:

EventLoop(线程组件,最核心组件),

Channel(通信通道,netty做了一层封装),

Pipeline(消息通知链),

ChannelHandler(真正触发事件干活的),

ChannelHandlerContext(对handler做了一层包装)

你可能感兴趣的:(网络,java,开发语言)