Nginx高效核心
目录
- Nginx高效核心
- Introduction
- I/O特性
- 同步/异步
- 阻塞/非阻塞
- 常见的I/O模型
- 阻塞型
- 非阻塞型
- 多路复用模型(多路阻塞)
- 信号驱动模型
- 异步模型
- Nginx中的I/O模型
- Reference
Introduction
做最近的软工作业的时候,需要部署网站,比较了多款Web服务器之后,选择了短小精悍的Nginx,本文记录学习Nginx过程中理解到的Nginx高效的核心原因。
Nginx,Engine X简称,是一个高性能的HTTP服务器,和其他同类产品相比,Nginx一直以内存小、高并发闻名。
访问Nginx服务器,大致可以归结为一个网络I/O过程,而网络I/O的本质上是socket流的读取。对于socket流而言,通常分为两步,将数据从磁盘准备好然后从内核缓冲区复制到应用进程缓冲区,然后进行传送过程。
I/O特性
同步/异步
调用者、被调用者的消息的通信机制
- 同步:调用者等待被调用者返回消息,才能继续执行,通常表现为轮询
- 异步:被调用者通过状态、通知、回调等机制通知调用者自己的运行状态
阻塞/非阻塞
调用者在调用结束之前所处的状态
- 阻塞:当调用结束之前,调用者被挂起
- 非阻塞:无需等到调用结束,调用者可以继续执行其他任务
常见的I/O模型
下面的五种常见模型,前四种都是同步模型
阻塞型
在数据拷贝(内核空间、用户空间之间)完成之前,进程会一直阻塞,直到完成。如下图:
发起recvfrom()调用的时候,系统会检查是否有准备好的数据,如果没有则等待(阻塞),当数据准备完成之后,将数据从内核空间复制到用户空间(依然阻塞),然后再返回。
非阻塞型
在数据拷贝(内核空间、用户空间之间)完成之前,进程不会一直阻塞,而是会继续执。如下图:
发起recvfrom()调用的时候,如果没有准备好的数据,进程会继续执行,但是执行过程中会轮询测试系统调用的状态,准备好之后再复制数据(阻塞),尽管比阻塞型有所改善,但轮询会消耗大量计算资源。
多路复用模型(多路阻塞)
多路复用是指对于一个I/O端口,可以多次调用,多次返回。如下图:
当进程发起select()调用的时候,这个函数也会使进程阻塞,但是和阻塞I/O不同的,它可以同时阻塞多个I/O操作,而且可以同时对多个读/写操作的I/O进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。
信号驱动模型
仍然是多次调用多次返回,如下图:
I/O伊始,给socket对应一个信号处理函数,然后进程继续执行,当数据准备完成之后,进程会受到一个SIGIO信号,然后调用信号处理函数进程I/O处理(仍然阻塞)。
异步模型
数据复制的时候无需阻塞,如下图:
当发起aio_read()调用的时候,调用者不会立刻得到结果,二十要等所有操作结束之后才通知信号处理程序。
Nginx中的I/O模型
nginx 支持多种并发模型,并发模型的具体实现根据系统平台而有所不同。在支持多种并发模型的平台上,nginx自动选择最高效的模型,当然也可以手动指定。
Nginx的高并发性能正是因为Nginx采用了异步I/O模型(epoll()),而Apache等服务器采用的多路复用模型(select)。
epoll()优点:
- 理论并发数无上限
- 内存映射机制