BIO、NIO、AIO

BIO:

  • 阻塞式
  • 面向流
  • 线程多
  • 性能差

NIO:

  • 非阻塞
  • 面向管道
  • 线程少
  • 性能好

Tomcat 演示

注意:最新版已经移除了 BIO 的实现,所以请使用旧版做测试。

server.xml:

  1. <!-- BIO 配置 -->
  2. <Connector port="8080" protocol="HTTP/1.1"
  3. connectionTimeout="20000"
  4. redirectPort="8443" maxThreads="500" />
  5. <!-- NIO 配置 -->
  6. <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
  7. connectionTimeout="20000"
  8. 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

image.png

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

image.png


Tomcat 源码:


Netty:

NIO:

  • API
  • 线程池
  • 线程模型:Reactor

Netty:

  • API
    • Pipeline
    • Bootstrap
    • ChannelHandler
  • 应用协议
    • HTTP
    • WebSocket
    • Email
    • 自定义
  • 编码器
    • 自定义
  • 零拷贝
  • TCP 拆粘包