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 做了封装:
- EventLoop:事件循环线程,一个线程绑定一个 Selector,循环做:轮询 IO 事件、处理连接、读写数据、执行任务。
- NioServerSocketChannel:服务端通道,对应服务端 Socket;
- NioSocketChannel:客户端连接通道;
- ChannelPipeline:责任链,读写事件在多个 Handler 之间传递(编解码、业务逻辑);
- ByteBuf:Netty 自研缓冲区,替代 Java NIO ByteBuffer,优化内存池、零拷贝。
Netty 底层就是调用
java.nio包的类,Netty 本身不直接发起操作系统 syscall。
第二层:Java NIO(JDK 封装层,java.nio)
Java NIO 是 JDK 提供的非阻塞 IO 库,是 Java 程序和操作系统之间的中间层。 核心组件:
- Selector(多路复用器)
- Linux:JDK NIO Selector 默认底层封装 epoll;
- Windows:JDK NIO Selector 底层封装 IOCP;
- MacOS:JDK NIO Selector 底层封装 kqueue;
- ServerSocketChannel:非阻塞服务端 Socket,监听端口;
- SocketChannel:非阻塞客户端通信通道;
- ByteBuffer:NIO 原生字节缓冲区。
Java NIO 的所有操作,最终都会通过 JVM 的 Native 方法(JNI),调用操作系统 C 库,再触发系统调用。
第三层:操作系统系统调用(OS 内核层)
系统调用:用户态程序向操作系统内核请求服务的入口。
Linux(epoll 模型)
Netty 在 Linux 下可以切换 epoll 原生实现:Netty 自带 EpollEventLoopGroup,不使用 JDK NIO Selector,直接通过 JNI 调用 Linux epoll 系统调用,跳过 JDK NIO 封装,性能更高。
epoll_create:创建 epoll 实例;epoll_ctl:注册 / 删除 socket 到 epoll;epoll_wait:阻塞等待 IO 就绪事件(可读、可写、连接到来);socket()创建套接字;bind()绑定端口;listen()开启监听;accept()接收新连接;send()/recv()收发 TCP 数据。
Windows(IOCP 完成端口)
Windows 没有 epoll,使用 IOCP 异步 IO 模型:
WSASocket创建 Windows 网络套接字;CreateIoCompletionPort创建完成端口;WSAAccept接收连接;WSASend/WSARecv异步收发数据;GetQueuedCompletionStatus获取 IO 完成事件。
MacOS(kqueue)
类 epoll 的多路复用模型:
kqueue()创建队列;kevent()注册事件、等待事件;- socket、bind、listen、accept、send/recv 基础网络系统调用。