I/O 与网络核心知识
做 Java 后端开发,几乎离不开 I/O。
写 REST API 要处理 HTTP 请求,连接数据库要处理网络 I/O,文件上传要处理磁盘 I/O,高性能网关要用 NIO/Netty。而这些 I/O 模型的底层,藏着大多数工程师的知识盲区——很多人能写出"能用"的代码,但说不清楚 BIO/NIO/AIO 到底有什么区别,不知道零拷贝为什么能提升性能,更不知道 Netty 的线程模型是怎么做到高并发的。
我自己在做一个长连接推送服务时,最初用 BIO 写,单机连了 5000 个客户端就开始频繁 OOM。换成 NIO 后,连接数轻松撑到 10 万。
这套内容,就是帮你把 I/O 和网络从底层原理到框架实现全部打通。
内容总览
Java I/O 可以分为三个层次:
知识全景
传统 I/O: BIO 🟡
BIO(Blocking I/O)是 Java 最早的 I/O 模式。一个连接一个线程,accept() 和 read() 都是阻塞调用。在低并发场景下简单好用,但连接数一多,线程资源很快耗尽。
NIO 核心: 三组件协同 🔴🔴
NIO 核心组件(Channel/Buffer/Selector)
NIO(Non-blocking I/O)通过三个核心组件实现了单线程处理大量连接的能力:
- Channel:类似流但双向,可以非阻塞读写
- Buffer:数据缓冲区,有 position/limit/capacity 三个指针
- Selector:一个线程监控多个 Channel 的事件(accept/read/write)
NIO 的非阻塞是针对 I/O 操作本身不阻塞,而不是"不需要等待数据"。Selector 告诉你"某个 Channel 可读",但数据还是要从内核缓冲区复制到用户缓冲区。真正的零拷贝需要配合 sendfile/mmap 等系统调用。
AIO(异步IO)原理 — 真正的异步:CompletionHandler + Future,JDK 7+ 支持
零拷贝: 性能关键 🔴
零拷贝是高性能网络服务的关键技术。传统 I/O 需要 4 次数据拷贝和 2 次上下文切换,sendfile 可以减少到 2 次拷贝,Linux 2.4+ 甚至可以做到 1 次拷贝。
Kafka 和 RocketMQ 为什么这么快?就是因为大量使用了零拷贝。
I/O 模型对比 🟡
选型建议:
- 小并发、简单逻辑 → BIO
- 高并发网络服务 → NIO(Netty)
- 需要真正异步通知 → AIO
Netty: 高性能网络框架 🔴🔴
Netty 是 Java 生态中最重要的高性能网络框架,Dubbo gRPC、Kafka、Finagle 都在用。
Netty 线程模型(Reactor) — Boss Group 接收连接,Worker Group 处理 I/O
Netty 核心组件(Channel/EventLoop/Pipeline) — ChannelPipeline 的入站/出站处理器链
Netty 零拷贝实现 — CompositeByteBuf/slice()/FileRegion
Netty 粘包/拆包解决方案 — LengthFieldBasedFrameDecoder
Netty 的核心设计哲学是"Pipeline + EventLoop"。Pipeline 让处理器链高度可组合,EventLoop 让单线程高效处理所有 I/O 事件。理解这两个核心概念,就理解了一半的 Netty。
序列化协议 🟡
序列化协议对比(Java/JSON/ProtoBuf/Hessian)
序列化是网络通信的基础。选对序列化协议,性能可以差 5~10 倍。
选型建议:
- 内部微服务通信 → Hessian / Kryo(高性能二进制)
- 对外 API / 需要跨语言 → JSON / Protocol Buffers
- 超高性能内部 RPC → Protocol Buffers
面试关联
I/O 与网络和其他 Java 模块紧密相连:
- NIO Selector → Linux Epoll、Redis 单线程模型
- 零拷贝 → Kafka 高吞吐原理
- Netty → Dubbo 网络通信、gRPC 原理
- 序列化 → MyBatis TypeHandler、Jackson 原理
阅读建议
记住:I/O 是性能的关键瓶颈之一。理解 NIO 和 Netty 的设计思路,才能写出真正高性能的网络服务。零拷贝、Reactor 模式、非阻塞 I/O——这些不只是面试考点,更是工程能力的重要体现。