在 Java 高并发网络编程中,I/O 模型是最核心的基础之一。
如果你学习过 Netty、Redis、Nginx、网关、RPC 框架,一定会遇到三个概念:
- BIO(Blocking IO)
- NIO(Non-Blocking IO)
- AIO(Asynchronous IO)
很多文章只是简单介绍概念,但真正面试或者做系统设计时,需要理解:
- I/O 架构图
- Reactor 模型
- Linux epoll
- Netty 线程模型
这篇文章会 从架构 → 底层 → 面试题完整讲清楚。
一、三种 I/O 模型对比(超清架构图)
1 BIO 架构图(同步阻塞)
Server
│
┌─────────┼─────────┐
│ │ │
Thread1 Thread2 Thread3
│ │ │
Client1 Client2 Client3
工作方式:
客户端连接
↓
创建线程
↓
线程阻塞等待数据
↓
处理请求
特点:
- 一个连接 → 一个线程
- 线程会阻塞等待 IO
问题:
10000 个连接
≈
10000 个线程
会导致:
- 线程上下文切换严重
- 内存消耗巨大
- CPU 利用率低
因此 BIO 不适合高并发系统。
二、NIO 架构图(非阻塞 IO)
NIO 的核心思想:
一个线程管理多个连接
架构:
┌──────────────┐
Client1 ───────────→ │ │
Client2 ───────────→ │ │
Client3 ───────────→ │ Selector │
Client4 ───────────→ │ │
Client5 ───────────→ │ │
└──────┬───────┘
│
Worker
│
业务处理
流程:
客户端连接
↓
注册到 Selector
↓
Selector 监听事件
↓
有 IO 事件触发
↓
线程处理
NIO 核心组件:
Channel
Buffer
Selector
特点:
- 一个线程管理多个连接
- 事件驱动
- 非阻塞
适合:
高并发服务器
聊天系统
网关系统
三、AIO 架构图(异步 IO)
AIO 的核心思想:
操作系统负责完成 IO
完成后通知程序
架构:
Application
│
发起 IO 请求
│
▼
Operating System
│
执行 IO
│
IO 完成
│
回调通知
▼
Application Callback
流程:
提交 IO 请求
↓
系统异步执行
↓
IO 完成
↓
回调通知程序
特点:
- 真正异步
- 不需要轮询
- 编程复杂
但在 Linux 上:
支持不够成熟
所以实际使用 远少于 NIO。
四、Netty Reactor 模型
Netty 使用的是:
NIO + Reactor
Reactor 是一种 事件驱动架构模型。
核心思想:
监听事件
↓
分发事件
↓
处理事件
Reactor 架构图
┌──────────────┐
Client Request →│ Reactor │
└──────┬───────┘
│
Event Dispatch
│
┌────────────┴────────────┐
│ │
Handler1 Handler2
│ │
Business Logic Business Logic
作用:
统一监听 IO 事件
统一分发业务处理
五、Netty 完整线程模型图(主从 Reactor)
Netty 实际使用:
主从 Reactor 模型
线程结构:
┌──────────────┐
Client ───────→ │ BossGroup │
└──────┬───────┘
│
接收连接
│
▼
┌──────────────┐
│ WorkerGroup │
└──────┬───────┘
│
处理读写 IO 事件
│
▼
┌──────────────┐
│ Pipeline │
└──────┬───────┘
│
Handler1 → Handler2 → Handler3
│
业务处理
执行流程:
客户端连接
↓
Boss 接收连接
↓
分配到 Worker
↓
Worker 处理 IO
↓
Pipeline 执行业务 Handler
优势:
- 线程模型清晰
- 支持高并发
- 扩展性强
六、NIO + epoll 底层原理
NIO 在 Linux 上依赖:
epoll
epoll 是 Linux 的 高性能 IO 多路复用机制。
传统 select / poll
早期 IO 模型:
select
poll
问题:
需要遍历所有连接
假设:
10000 个连接
只有 1 个有数据
select 仍然要:
遍历 10000 次
效率低。
epoll 工作方式
epoll 使用:
事件通知机制
架构:
┌────────────┐
Client Conn → │ epoll │
└─────┬──────┘
│
有事件的连接
│
返回
│
程序处理
优势:
只返回有事件的连接
复杂度:
O(1)
因此:
Redis
Nginx
Netty
Kafka
全部基于 epoll。
七、BIO / NIO / AIO 对比总结
| 模型 | 类型 | 线程模型 | 并发能力 |
|---|---|---|---|
| BIO | 同步阻塞 | 一连接一线程 | 低 |
| NIO | 同步非阻塞 | 少量线程 | 高 |
| AIO | 异步非阻塞 | 回调 | 极高 |
一句话总结:
BIO:线程等待 IO
NIO:线程轮询 IO
AIO:系统完成 IO
八、大厂面试高频题(10题)
1 BIO、NIO、AIO 的区别?
核心区别:
BIO:同步阻塞
NIO:同步非阻塞
AIO:异步非阻塞
2 为什么 NIO 可以支持高并发?
因为:
一个线程可以管理多个连接
减少:
- 线程创建
- 线程切换
- 内存开销
3 NIO 三大核心组件?
Channel
Buffer
Selector
4 什么是 IO 多路复用?
IO 多路复用:
一个线程监听多个 IO
典型实现:
select
poll
epoll
5 epoll 为什么比 select 快?
因为:
epoll 不需要遍历所有连接
只返回:
有事件的连接
6 Netty 为什么这么快?
原因:
NIO
Reactor 模型
epoll
零拷贝
线程池
7 什么是 Reactor 模型?
Reactor 是一种:
事件驱动架构
核心流程:
事件监听
事件分发
事件处理
8 Netty 为什么不用 AIO?
原因:
Linux AIO 不成熟
NIO 已经足够快
生态更稳定
9 什么是零拷贝?
零拷贝指:
减少 CPU 数据复制
提升:
网络 IO 性能
10 Netty 的线程模型是什么?
Netty 使用:
主从 Reactor
结构:
BossGroup
WorkerGroup
Pipeline
Handler
九、总结
Java 网络 IO 发展:
BIO → NIO → AIO
但在实际工程中:
NIO + Reactor + epoll
仍然是 高并发服务器的主流架构。
所以像:
Netty
Redis
Nginx
Kafka
底层思想几乎一致。
如果你想深入 Netty / 高并发 / 分布式系统,理解这套 IO 模型是非常重要的一步。