nginx中的epoll模型
要了解epoll模型,就要一个一个知识点由浅至深地去探索。
1.IO复用技术

IO流请求操作系统内核,有串行处理和并行处理两种概念。
串行处理是前面一个操作处理地时候,后面的所有操作都需要等待。因此,必须考虑以并行处理的方式来完成整个IO流的请求,实现最大的并发和吞吐。这里就用到了IO复用技术。
IO复用技术就是让一个Socket来做复用完成整个IO流的请求。实现IO流的请求其中一种方式就是多线程,但是多线程会占用大量资源,不便于管理,因此又出现了IO多路复用技术。
2.IO多路复用技术
IO多路复用是指多个描述符的I/O操作都能在一个线程内并发交替地顺序完成,这里的复用指的是复用同一个线程。
对操作系统内核而言,多路复用其实是要完成操作系统IO的请求,对于IO文件的请求,当一个IO流要进行对应的文件处理的时候,要获取一组文件的描述符,当文件描述符还没就绪的时候,它就一直在等待,直到描述符就绪,就马上上报系统的一个通知的机制,以此来告诉主应用程序它已经准备就绪了,你可以来操作了。这种方式就是IO多路复用方式。
3.IO多路复用技术的实现
IO多路复用技术的实现方式有select、poll和epoll,它们都是linux内核下的常见多路复用模型。
其中最早出现的是select模型。
4.select模型
多路复用其实就是内核态对IO请求的时候,会主动地发送所需要处理的文件对象就绪时文件的就绪信息给应用端,应用端在FD(File Description)没有就绪之前都是block,也就是阻塞对应的Socket请求,也会维护一个FD的列表。当内核态发送可用的信息,FD就绪之后,应用端采用select这种模式,会一直在遍历所维护的FD文件描述符的列表,以等到唤醒对应的线程完成对应的数据拷贝。select模型能够监视文件描述符的数量存在最大限制,且在整个过程中,select模型采用的是线性遍历的模式,这种模式效率低下。

5.epoll模型
epoll模型优化和完善了select模式的缺点,每当FD就绪,采用系统的回调函数直接将FD放入,效率高,无监视文件描述符的数量限制。
6.epoll模型的原理
设想一个场景:有100万用户同时与一个进程保持着TCP连接,而每一时刻只有几十个或几百个TCP连接是活跃的(接收到TCP包),也就是说,在每一时刻,进程只需要处理这100万个连接中的一小部分连接。那么,如何才能高效地处理这种场景呢?进程是否在每次询问操作系统收集有事件发生的TCP连接时,把这100万个连接告诉操作系统,然后由操作系统找出其中有事件发生的几百个连接呢?实际上,在Linux内核2.4版本之前,select或poll事件驱动模型就是这样处理的。
这里有个非常明显的问题,即在某一时刻,进程收集有事件的连接时,其实这100万连接中的大部分是没有事件发生的。因此,如果每次收集事件时,都把这100万连接的套接字传给操作系统(这首先就是用户态内存到内核态内存的大量复制),而由操作系统内核寻找这些连接上有没有未处理的事件,将会是巨大的资源浪费,然而select和poll就是这样做的,因此它们最多只能处理几千个并发连接。
而epoll就厉害了,它会在Linux内核中申请一个简易的文件系统,把原先的一个select或poll调用分成了3个部分:
1.调用epoll_create创建一个epoll对象(在epoll文件系统中给这个句柄分配资源,一棵红黑树和一个准备就绪list链表)。
2.调用epoll_ctl向epoll对象中添加这100万个连接的套接字。就是把socket放到红黑树上,给内核中断处理程序注册一个回调函数,然后告诉内核如果这个句柄的中断到了,就把这个socket放到准备就绪list链表里。
3.调用epoll_wait收集发生事件的TCP连接。到准备就绪list链表中处理socket,并把数据返回给用户。
这样,只需要在进程启动的时候建立1个epoll对象,并在需要的时候向它添加或删除连接即可。因此在实际收集事件时,epoll_wait的效率会非常高,因为调用epoll_wait时并没有向它传递这100万个连接,内核也不需要去遍历所有的连接,只需要到就绪list链表中去处理socket就行了。
"曾经以为拥有一点点可能的人,终究还是不可能。"
nginx中的epoll模型的更多相关文章
- Nginx 所使用的 epoll 模型是什么?
对于 Nginx,相信有过 Web 服务部署经验的同学都不陌生,它有以下特点: 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx 相较于 A ...
- Nginx源码研究三:Epoll在NGINX中的使用
Web服务器在面对高并发的情况下,网络的IO一般选择IO复用,像apache选择的Select/poll.Nginx在linux 2.6后选择Epoll做网路IO,提高了WEB服务的并发能力. 在本章 ...
- nginx中时间的管理
nginx出于性能考虑採用类似lib_event的方式,自己对时间进行了cache,用来降低对gettimeofday()的调用,由于一般来说server对时间的精度要求不是特别的高,只是假设须要比較 ...
- Nginx 中 nginx.conf 详解
#定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_processes 8; #全局错误日志定义类型,[ debug | ...
- 并发编程-epoll模型的探索与实践
前言 我们知道nginx的效率非常高,能处理上万级的并发,其之所以高效离不开epoll的支持, epoll是什么呢?,epoll是IO模型中的一种,属于多路复用IO模型; 到这里你应该想到了,sele ...
- nginx中使用srcache_nginx模块构建缓存
nginx中可以将lua嵌,让nginx执行lua脚本,可以处理高并发,非阻塞的处理各种请求,openresty项目中可以使用nignx可以直接构建 srcache_nginx + redis 缓存, ...
- Epoll模型详解
Linux 2.6内核中提高网络I/O性能的新方法-epoll I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数. 1.为什么select落后 首先,在Lin ...
- 【转】select和epoll模型的差异
http://www.cppblog.com/converse/archive/2008/10/12/63836.html epoll为什么这么快 epoll是多路复用IO(I/O Multiplex ...
- linux epoll模型
原文:http://yjtjh.blog.51cto.com/1060831/294119 Linux I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数.Linux ...
随机推荐
- Vs Code 插件配置教程
1 Vs Code 下载地址:https://code.visualstudio.com/ 2 安装好Vs Code,点击启动,点击File-> Open Folder 打开项目 3 点击E ...
- Error - The debugger's worker process (msvsmon.exe) unexpectedly exited.
Error - The debugger's worker process (msvsmon.exe) unexpectedly exited. 解决方法:Tools->Options-> ...
- [Go] 使用go语言解决现代编程难题
1.计算机一直在演化,64核,128核等等,但是我们依旧在使用为单核设计的技术编程2.Go语言让分享自己的代码包更容易3.Go语言重新思考传统的面向对象,提供了更高效的复用代码手段4.Go不仅提供高性 ...
- C#/VB.NET 操作Word批注(二)——如何插入图片、读取、回复Word批注内容
序 在前面的文章C# 如何插入.修改.删除Word批注一文中介绍了如何操作Word批注的一些方法,在本篇文章中继续介绍操作Word批注的方法.分以下三种情况来介绍: 1. 插入图片到Word批注 2. ...
- Java开发笔记(三十七)利用正则串分割字符串
前面介绍了处理字符串的常用方法,还有一种分割字符串的场景也很常见,也就是按照某个规则将字符串切割为若干子串.分割规则通常是指定某个分隔符,根据字符串内部的分隔符将字符串进行分割,例如逗号.空格等等都可 ...
- Hibernate框架笔记01_环境搭建_API_CRUD
目录 1. Hibernate框架的概述 1.1 什么是框架 1.2 经典三层架构 1.3 Hibernate框架 2 Hibernate入门 2.1 下载Hibernate的开发包 2.2 创建项目 ...
- 原生JS实现简易轮播图
原生JS实现简易轮播图(渐变?) 最近做网页总是会用到轮播图,我就把之前写的轮播图单独拿出来吧,如果有...如果真的有人也需要也可以复制去用用啊..哈~.. window.onload = funct ...
- ASP.NET Core介绍
认识ASP.NET Core ASP.NET Core是一个跨平台,高性能,开源的框架,用于构建现代,基于云的网络应用程序,使用ASP.NET Core可以实现: 开发web应用,服务,IoT应用和移 ...
- Python全栈开发之---mysql数据库
1.数据库的安装和连接 #数据库安装 pip install PyMySQL #数据库操作 import pymysql db = pymysql.connect("数据库ip", ...
- java 应用程序的编译和运行
1.java 文件的编译和执行步骤. 第一步:使用编辑器编辑 后缀为java的文件,里面包含主类(包含 main()函数), 源文件的命名规则是,如果源文件中有多个类,那么只能有一个类是public ...