BIO、NIO、AIO
BIO:
- 阻塞式
- 面向流
- 线程多
- 性能差
NIO:
- 非阻塞
- 面向管道
- 线程少
- 性能好
Tomcat 演示
注意:最新版已经移除了 BIO 的实现,所以请使用旧版做测试。
server.xml:
<!-- BIO 配置 -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" maxThreads="500" />
<!-- NIO 配置 -->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" maxThreads="500" />
默认线程最小值为 10
客户端每秒 50 个请求,启动 4 个客户端,TPS 为 200
服务端会根据请求数量,自动地增加线程数量
场景1:代码中没有任何延迟,客户端到服务端也没有
BIO:20 个线程
NIO:为默认的最小值 10 个线程
场景2:客户端建立连接后,休眠 2s,然后再发送数据
BIO:449 个线程
NIO:10 个线程,且每占满
影响 NIO 的因素:
服务端:
- 同步执行 SQL
- 调用第三方服务
- 执行消耗 CPU 的操作,比如复杂的正则表达式
- 服务端线程阻塞:sleep,lock,wait
NIO 线程模型:
Acceptor 线程组:接收连接,封装 Task
- http-nio-8080-Acceptor-0
IO 线程组:接收读写事件,并分配给 Worker 线程组。Selector()
- http-nio-8080-ClientPoller-0
- http-nio-8080-ClientPoller-1
Worker 线程组:处理读写事件
- http-nio-8080-exec-1
- http-nio-8080-exec-2
- …
Tomcat 源码:
Netty:
NIO:
- API
- 线程池
- 线程模型:Reactor
Netty:
- API
- Pipeline
- Bootstrap
- ChannelHandler
- 应用协议
- HTTP
- WebSocket
- 自定义
- 编码器
- 自定义
- 零拷贝
- TCP 拆粘包