对于 Nginx,相信有过 Web 服务部署经验的同学都不陌生,它有以下特点:

  • 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。
  • Nginx 相较于 Apache 具有占有内存少,稳定性高等优势,并且依靠并发能力强,丰富的模块库以及友好灵活的配置而闻名。

Nginx 目前部署量逐渐增加,大多数运维人员多多少少都懂点 Nginx,但是真正其明白原理的可能少之又少,在许多面试中可能就 Nginx 会涉及一些实现层面的问题。比如一道阿里的面试题是:说说看 Nginx 所使用的 epoll 模型是什么?

错误回答:Nginx 相比较其他服务器来说就是快,高并发,快速响应,因为用了 epoll......

所以 epoll 以及一般可以同时见到的 select 或者 poll 分别是什么呢?

三个都是 IO 多路复用的机制,可以监视多个描述符的读 / 写等事件,一旦某个描述符就绪(一般是读或者写事件发生了),就能够将发生的事件通知给关心的应用程序去处理该事件。

一些 Linux 知识铺垫

在实际开始前,我们先回顾一点 Linux 的知识,对于 Linux 而言:

一切都是文件

然而为了区分不同类型的事物,我们有了:

  • 普通文件
  • 目录文件
  • 链接文件
  • 设备文件

其中文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其值是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行 I/O 操作的系统调用都通过文件描述符。

如果直接这么讲可能有些难以理解,对于 Linux 有一些使用的用户来说,会有类似如下的写法:

g++ lots_of_errors 2>&1 | head

其中 2>&1中的 2 就是表示的「标准错误」,1 就是「标准输出」,中间的 & 表示后面跟的数字是文件描述符而不是一个文件(不然所有的「标准错误」就都重定向到了一个名为 1 的文件中了)。

有了上面的知识,我们就可以开始来探索 select,poll 和 epoll 分别是什么了~

多路复用

如文初的说明表示,这三者都是 I/O 多路复用机制,且简要介绍了多路复用的定义,那么如何更加直观地了解多路复用呢?

这里有张图:

对于网页服务器 Nginx 来说,会有很多连接进来, epoll 会把他们都监视起来,然后像拨开关一样,谁有数据就拨向谁,然后调用相应的代码处理。

一般来说以下场合需要使用 I/O 多路复用:

  • 当客户处理多个描述字时(一般是交互式输入和网络套接口)
  • 如果一个服务器既要处理 TCP,又要处理 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)

对应的头文件和函数原型为:

poll 和 select 原理一样,不过相比较 select 而言,poll 可以支持大于 1024 个文件描述符。

epoll (2002)

对应的头文件和函数原型为:

相比较 select 和 poll,epoll 的最大特点是:

  • epoll 现在是线程安全的,而 select 和 poll 不是。
  • epoll 内部使用了 mmap 共享了用户和内核的部分空间,避免了数据的来回拷贝。
  • epoll 基于事件驱动,epoll_ctl 注册事件并注册 callback 回调函数,epoll_wait 只返回发生的事件避免了像 select 和 poll 对事件的整个轮寻操作。

什么是回调?一个简单的例子:

  • 四六级考试成绩快要出来的那段时间,小张每隔一段时间就去尝试查一下成绩,这个被称为轮训。
  • 小张并不在意疯狂刷新页面的事情,等到四六级成绩出来之后他的手机会自动收到考试院推送的一个小时:「叮,你的六级没过」,这样就是回调。

另一个方便理解的对比如下:

  • 对于 select / poll 模型来说,可以理解为让酒店代理订票,然后每隔几个小时就问一下买到没有,酒店在第二天订到了票,交钱给酒店拿到票,这样会需要额外的打电话时间和精力。
  • 对于 epoll 来说则是委托酒店帮忙订票,但是并不反复去问,酒店在第二天买到了票,酒店打电话通知来领票,交钱给酒店拿到票。

epoll 和 Nginx

回到文章开头,最后我们可以简单总结一下为什么有了 epoll 的 Nginx 会有很高的运行效率,其原因在于它使用了异步,非阻塞,IO 多路复用。但是我们是不是就应该吹爆 Nginx,表示「Nginx 完爆 Apache」呢?

其实不是,相比较 Nginx 而言,Apache 作为一个非常老牌的网页服务器,其有丰富的模块组件支持,稳定性强,BUG 少,动态内容处理强,而 Nginx 的优势主要则在于占用资源少,负载均衡,高并发处理强,静态内容处理高效,所有只有掌握了自己的具体业务场景,才可以分情况地讨论这两个服务器之间的区别。

对于 Nginx 而言,其实还有许多高频面试题,例如:

  • Nginx 常用命令有哪些?

需要熟悉:nginx -t ,nginx -s stop 之类

  • Nginx 返回 502 错误的可能原因?

这个得分情况分类讨论,一般可能是后端服务器挂了,也有可能是 Proxy Buffer 不够

  • 正向代理和反向代理之间的区别是什么?

正向代理:代理端代理的是客户端反向代理:代理端代理的是服务端

  • 什么是负载均衡?

代理服务器将接收的请求均衡的分发到各服务器

本文作者:Nova Kwok

声明:本文归 “力扣” 版权所有,如需转载请联系。

文中部分图片来源于网络,为非商业用途使用,如有侵权联系删除。

Nginx 所使用的 epoll 模型是什么?的更多相关文章

  1. nginx中的epoll模型

    要了解epoll模型,就要一个一个知识点由浅至深地去探索. 1.IO复用技术 IO流请求操作系统内核,有串行处理和并行处理两种概念. 串行处理是前面一个操作处理地时候,后面的所有操作都需要等待.因此, ...

  2. Nginx事件管理机制-epoll

    epoll的最大好处在于他不会随着被监控描述符的数目的增长而导致效率极致下降. select是遍历扫描来判断每个描述符是否有事件发生,当监控的描述付越多时,时间消耗就越多,并且由于系统的限制selec ...

  3. 并发编程-epoll模型的探索与实践

    前言 我们知道nginx的效率非常高,能处理上万级的并发,其之所以高效离不开epoll的支持, epoll是什么呢?,epoll是IO模型中的一种,属于多路复用IO模型; 到这里你应该想到了,sele ...

  4. nginx架构分析之 事件驱动模型

    事件驱动模型 事件驱动模型是实现异步非阻塞的一个手段.事件驱动模型中,一个进程(线程)就可以了. 对于web服务器来说,客户端A的请求连接到服务端时,服务端的某个进程(Nginx worker pro ...

  5. Epoll模型详解

    Linux 2.6内核中提高网络I/O性能的新方法-epoll I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数. 1.为什么select落后    首先,在Lin ...

  6. 【转】select和epoll模型的差异

    http://www.cppblog.com/converse/archive/2008/10/12/63836.html epoll为什么这么快 epoll是多路复用IO(I/O Multiplex ...

  7. linux epoll模型

    原文:http://yjtjh.blog.51cto.com/1060831/294119 Linux I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数.Linux ...

  8. Linux网络服务器epoll模型的socket通讯的实现(一)

    准备写一个网络游戏的服务器的通讯模块,参考网上看到的一些代码,在linux下面实现一个多线程的epoll模型的socket通讯的代码,以下是第一部分多线程的切换代码: 1 #include <s ...

  9. (OK) Linux epoll模型—socket epoll server client chat

    http://www.cnblogs.com/venow/archive/2012/11/30/2790031.html http://blog.csdn.net/denkensk/article/d ...

随机推荐

  1. Go path/filepath文件路径操作

    本文:https://books.studygolang.com/The-Golang-Standard-Library-by-Example/chapter06/06.2.html path:htt ...

  2. nginx mirror/post_action+gor实现https流量复制

    关于gor: 参考: https://www.cnblogs.com/jinjiangongzuoshi/p/11773070.html https://github.com/buger/gorepl ...

  3. Nginx的proxy buffer参数总结

    1. proxy_buffering 语法:proxy_buffering on|off 默认值:proxy_buffering on 上下文:http,server,location 作用:该指令开 ...

  4. Mysql中decode函数的几种用法

    1.使用decode判断字符串是否一样 decode(value,if1,then1,if2,then2,if3,then3,...,else) 含义为 IF 条件=值1 THEN RETURN(va ...

  5. Python JSON的简单使用

    1          json简介 1.1         json是什么? JSON(JavaScript Object Notation)是一种轻量级的数据交换格式. “在JSON出现之前,大家一 ...

  6. windows+phpstudy(apache) 以cgi方式运行python

    Apache配置 在httpd.conf中查找DocumentRoot: +ExecCGI 支持cgi DocumentRoot "F:\phpStud\PHPTutorial\WWW&qu ...

  7. vue-cli3.0 脚手架搭建项目的过程详解

    1.安装vue-cli 3.0 ? 1 2 3 npm install -g @vue/cli # or yarn global add @vue/cli 安装成功后查看版本:vue -V(大写的V) ...

  8. CentOS7安装Redis单实例

    由于环境差异,安装过程可能遇到各种各样的问题,不要慌,根据错误提示解决即可. 1.下载redis下载地址在:redis.io比如把Redis安装到/usr/local/soft/ cd /usr/lo ...

  9. c#版本23个设计模式

    一.引言 对设计模式的学习,自己的感触还是很多的,因为我现在在写代码的时候,经常会想想这里能不能用什么设计模式来进行重构.所以,学完设计模式之后,感觉它会慢慢地影响到你写代码的思维方式.这里对设计模式 ...

  10. Docker容器化技术(下)

    Docker容器化技术(下) 一.Dockerfile基础命令 1.1.FROM - 基于基准镜像 FROM centos #制作基准镜像(基于centos) FROM scratch #不依赖任何基 ...