阿里巴巴面试题:Nginx使用的Epoll模型是什么?
作者:LeetCode
对于Nginx,相信有过Web服务部署经验的同学都会比较熟悉。它具有以下特点:
- 它是一个高性能的HTTP和反向代理服务器。 IMAP/POP3/SMTP 代理服务器。
- 与 Apache 相比,Nginx 具有占用内存少、稳定性高的优点。它还以其强大的竞赛能力、丰富的模块库、友好灵活的配置而闻名。
目前Nginx的部署量正在逐渐增加。大多数运维人员对Nginx有所了解,但真正了解其原理的可能很少。在很多采访中,Nginx 可能会涉及到一些实现层面的问题。例如,阿里巴巴的一个面试问题是:Nginx 使用的 epoll 模型是什么?
错误答案:相比其他服务器,Nginx 速度快、并发高、响应速度快,因为它使用了 epoll...?想要布料吗?
这三个都是IO复用机制,可以监控多个描述符的读/写事件。当特定描述符准备好时(通常是读或写事件发生),发生的事件就可以。
一些Linux知识铺路
在我们真正开始之前,我们先回顾一下一些Linux知识。对于Linux:
一切都是文件
但是,为了区分不同类型的事物,我们有:
- 普通文件
- 目录文件 e链接e
文件描述符(filedescriptor)是一个内核创建的索引,用于高效管理已打开的文件,其值为一个非负整数(通常是小整数),用于引用一个打开的文件。所有执行 I/O 操作的系统调用都会通过文件描述符。 ![]()
如果直接说的话可能会很难理解。对于某些Linux用户来说,有类似如下的脚本:
g++ lots_of_errors 2>&1 | head 其中,2和2>&1是“标准”错误,1是“标准输出”,其中的&中间显示后面的数字是文件描述符而不是文件(否则所有“标准错误”将被重定向到名为 1 的文件)。
有了上面的知识,我们就可以开始探索什么是selection、poll、epoll了~
复用
正如文章开头所说,这三个都是I/O的复用机制和定义简要介绍了复用的原理。那么如何更直观的理解多路复用呢?下面是一张图: ![]()
对于Web服务器Nginx来说,有很多连接进来,epoll都监视它们,然后像交换机一样,谁有数据,就选择它,然后调用相应的代码来处理。
一般情况下,以下情况需要 I/O 复用:
- 当客户端处理多个描述符时(通常是交互式输入和网络套接字)
- 当服务器需要同时处理 UDP 和处理 ,一般使用 I/O 多路复用
- 如果一个 TCP 服务器需要同时处理监听套接字和已连接套接字
select (1983)
相应的头文件和函数原型为: ♼❝ I/ 的概念O 多路复用被提出,select 是第一个实现。 select的调用流程图如下: ![]()
缺点是:
- 每次select都要将fd集合从用户态复制到内核态。如果fd很多的话这个开销会非常大
- 同时每次select都要突破内核中所有传递过来的fd。如果fd很多的话这个开销会很大。也很大
- Select支持的文件描述符数量只有1024个,很小
如果系统支持的文件描述符数量不足,在Linux上一般会出现如下:
Too many open files (24)这时候就需要通过类似: ulimit -n 2048 的方法来临时增加它。
poll (1997)
对应的头文件和函数原型为:
#include <sys/poll.h>
int poll (struct pollfd *fdarray, unsigned long nfds, int timeout);
/* Returns: count of ready descriptors, 0 on timeout, –1 on error */poll 与 select 原理相同,但与 select 相比,poll 可以支持超过 1024 个文件描述符。
epoll (2002)
对应的头文件和函数原型为:
#include <sys/epoll.h>
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);与 select 和 poll 相比,epoll 最大的特点是:
- -polle 是,而现在 thread 和 polle 不是。
- epoll内部使用mmap来共享部分用户和内核空间,避免来回复制数据。
- epoll 是事件驱动的。 epoll_ctl注册事件并注册callback回调函数。 epoll_wait只返回已经发生的事件,避免了选择、轮询等事件的整个轮询操作。
什么是召回?举个简单的例子:
- 在四六级成绩即将出炉的那段时间,小张每次都试图查看成绩。这称为轮换训练。
- 小张不疼不痒的刷新页面。四、六级成绩出来后,他的手机自动收到了考试中心一个小时的推送:“叮,你六级没及格。”这是一次回忆。
另外一个容易理解的对比如下:
- 对于select/survey模型,可以理解为酒店代理会订票,然后每隔几个小时询问是否有空,然后酒店会在“预订第二天取票”的时候,向酒店付款取票,这需要额外的时间和精力在电话上。
- 对于epoll来说,是委托酒店订票的,但并没有再三询问。第二天酒店就买了票,酒店打电话去取票,付了钱给酒店取票。
epoll与Nginx
回到文章开头,最后我们可以简单总结一下为什么Nginx配合epoll运行效率高。原因是它使用异步、非阻塞、IO 复用。但是我们应该抨击 Nginx 并说“Nginx 彻底摧毁了 Apache”吗?
其实不是。与 Nginx 相比,Apache 是一个非常古老的 Web 服务器。模块组件支持丰富,稳定性强,BUG少,动态内容处理能力强。 Nginx的主要优点是占用资源。少、负载均衡、强高并发处理、高效的静态内容处理。只有掌握了自己的具体业务场景,才能具体情况具体讨论两种服务器的差异。
对于Nginx来说,其实有很多高频面试题,比如:
- Nginx中常用的命令有哪些?
必须熟悉:nginx -t、nginx -s stop之类的♶ 之类的♶ 2有可能回归吗?
这个分数情况是分类讨论的。一般可能是后端服务器挂了,或者是代理缓冲区不够 - 正向代理和反向代理有什么区别?
正向代理:代理充当客户端的代理。反向代理:代理充当服务器的代理。 - 什么是负载均衡?
代理服务器将接收到的请求平均分配给所有服务器
本文作者:Nova Kwok
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网