基础知识深化:NIO优化原理和Tomcat线程模型

本文详细探讨了I/O性能的重要性,特别是网络I/O中的阻塞问题,以及如何通过NIO进行优化。文章介绍了NIO的非阻塞特性、Reactor模式及其在Tomcat线程模型中的应用,强调了NIO在高并发场景下的优势,并对比了BIO和NIO的区别。此外,还提及了Tomcat中不同线程模型的演变和适用场景。
摘要由CSDN通过智能技术生成

I/O(Input/Output)即数据的输入/输出,为什么大家很关心I/O的性能呢?因为I/O存在的范围很广,在高并发的场景下,这部分性能会被无限放大。而且与业务无关,是可以有统一解决方案的。

所有的系统I/O都分为两个阶段:等待就绪和数据操作。举例来说,读函数,分为等待系统可读和真正的读;同理,写函数分为等待网卡可以写和真正的写:

  1. 等待就绪 :等待数据就绪,一般是将数据加载到 内核缓存区 。无论是从磁盘、网络读取数据,程序能处理的都是进入内核态之后的数据,在这之前,cpu会阻塞住,等待数据进入内核态。

  2. 数据操作 :数据就绪后,一般是将内核缓存中的数据加载到 用户缓存区 。

需要说明的是等待就绪的阻塞是不使用CPU的,是在“空等”;而真正的读写操作的阻塞是使用CPU的,真正在”干活”,而且这个过程非常快,属于memory copy,带宽通常在1GB/s级别以上,可以理解为基本不耗时。这就出现一个奇怪的现象 – 不使用CPU的“等待就绪”,却比实际使用CPU的“数据操作”,占用CPU时间更多 。

传统阻塞I/O模型,即在读写数据过程中会发生阻塞现象。当用户线程发出I/O请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才会解除block状态。

明确的是,让当前工作线程阻塞,等待数据就绪,是很浪费线程资源的事情,上述三种I/O都有一定的优化方案:

  • 磁盘I/O :现代电脑中都有一个DMA(Direct Memory Access 直接内存访问) 的外设组件,可以将I/O数据直接传送到主存储器中并且传输不需要CPU的参与,以此将CPU解放出来去完成其他的事情。

  • 网络I/O :NIO、AIO等I/O模型,通过向事件选择器注册I/O事件,基于就绪的事情来驱动执行I/O操作,避免的等待过程。

  • 内存I/O :内存部分没涉及到太多阻塞,优化点在于减少用户态和内核态之间的数据拷贝。nio中的零拷贝就有mmap和sendfile等实现方案。

1.3、网络I/O阻塞

===============================================================================

这里仔细的讲讲网络I/O模型中的阻塞,即socket的阻塞。在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式,是在tcp/ip协议上,抽象出来的一层网络通讯协议。

同上面I/O的过程一样,网络I/O也同样分成两个部分:

  1. 等待网络数据到达网卡,读取到内核缓冲区。

  2. 从内核缓冲区复制数据到用户态空间。

每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区:

  • 输入缓冲区 :当使用 read()/recv() 读取数据时,(1)首先会检查缓冲区,如果缓冲区中有数据,那么就读取,否则函数会被阻塞,直到网络上有数据到来。(2)如果要读取的数据长度小于缓冲区中的数据长度,那么就不能一次性将缓冲区中的所有数据读出,剩余数据将不断积压,直到有 read()/recv() 函数再次读取。(3)直到读取到数据后 read()/recv() 函数才会返回,否则就一直被阻塞。

  • 输出缓冲区 :当使用 write()/send() 发送数据时,(1)首先会检查缓冲区,如果缓冲区的可用空间长度小于要发送的数据,那么 write()/send() 会被阻塞(暂停执行),直到缓冲区中的数据被发送到目标机器,腾出足够的空间࿰

  • 18
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值