Netty是一个由java编写的异步的,基于事件驱动的网络应用框架。

Netty业务代码
    ↓
Netty EventLoop / NioChannel
    ↓
Java NIO API(Selector、SocketChannel)
    ↓
JVM JNI Native方法
    ↓
操作系统系统调用(epoll / IOCP / kqueue)
    ↓
操作系统内核 TCP/IP协议栈
    ↓
网卡硬件

第一层:Netty(应用框架层)

Netty 是基于 Java NIO 封装的高性能网络框架,不直接操作系统调用,把 NIO 的繁琐 API 做了封装:

  1. EventLoop:事件循环线程,一个线程绑定一个 Selector,循环做:轮询 IO 事件、处理连接、读写数据、执行任务。
  2. NioServerSocketChannel:服务端通道,对应服务端 Socket;
  3. NioSocketChannel:客户端连接通道;
  4. ChannelPipeline:责任链,读写事件在多个 Handler 之间传递(编解码、业务逻辑);
  5. ByteBuf:Netty 自研缓冲区,替代 Java NIO ByteBuffer,优化内存池、零拷贝。

Netty 底层就是调用 java.nio 包的类,Netty 本身不直接发起操作系统 syscall。

第二层:Java NIO(JDK 封装层,java.nio)

Java NIO 是 JDK 提供的非阻塞 IO 库,是 Java 程序和操作系统之间的中间层。 核心组件:

  1. Selector(多路复用器)
    • Linux:JDK NIO Selector 默认底层封装 epoll;
    • Windows:JDK NIO Selector 底层封装 IOCP;
    • MacOS:JDK NIO Selector 底层封装 kqueue;
  2. ServerSocketChannel:非阻塞服务端 Socket,监听端口;
  3. SocketChannel:非阻塞客户端通信通道;
  4. ByteBuffer:NIO 原生字节缓冲区。

Java NIO 的所有操作,最终都会通过 JVM 的 Native 方法(JNI),调用操作系统 C 库,再触发系统调用。

第三层:操作系统系统调用(OS 内核层)

系统调用:用户态程序向操作系统内核请求服务的入口。

Linux(epoll 模型)

Netty 在 Linux 下可以切换 epoll 原生实现:Netty 自带 EpollEventLoopGroup,不使用 JDK NIO Selector,直接通过 JNI 调用 Linux epoll 系统调用,跳过 JDK NIO 封装,性能更高。

  1. epoll_create:创建 epoll 实例;
  2. epoll_ctl:注册 / 删除 socket 到 epoll;
  3. epoll_wait:阻塞等待 IO 就绪事件(可读、可写、连接到来);
  4. socket() 创建套接字;
  5. bind() 绑定端口;
  6. listen() 开启监听;
  7. accept() 接收新连接;
  8. send() / recv() 收发 TCP 数据。

Windows(IOCP 完成端口)

Windows 没有 epoll,使用 IOCP 异步 IO 模型:

  1. WSASocket 创建 Windows 网络套接字;
  2. CreateIoCompletionPort 创建完成端口;
  3. WSAAccept 接收连接;
  4. WSASend / WSARecv 异步收发数据;
  5. GetQueuedCompletionStatus 获取 IO 完成事件。

MacOS(kqueue)

类 epoll 的多路复用模型:

  1. kqueue() 创建队列;
  2. kevent() 注册事件、等待事件;
  3. socket、bind、listen、accept、send/recv 基础网络系统调用。