Nginx支持比Apache高并发的原因
1.先从各自使用的多路复用IO模型说起:
select模型:(apache使用,由于受模块等限制,用的不多)
- 单个进程能够 监视的文件描述符的数量存在最大限制
- select()所维护的 存储大量文件描述符的数据结构 ,随着文件描述符数量的增长,其在用户态和内核的地址空间的复制所引发的开销也会线性增长
- 由于网络响应时间的延迟使得大量TCP连接处于非活跃状态,但调用select()还是会对 所有的socket进行一次线性扫描 ,会造成一定的开销
poll:
poll是unix沿用select自己重新实现了一遍,唯一解决的问题是poll 没有最大文件描述符数量的限制
epoll模型:(nginx使用)
epoll带来了两个优势,大幅度提升了性能:
- 基于事件的就绪通知方式 ,select/poll方式,进程只有在调用一定的方法后,内核才会对所有监视的文件描述符进行扫描,而epoll事件通过epoll_ctl()注册一个文件描述符,一旦某个文件描述符就绪时,内核会采用类似call back的回调机制,迅速激活这个文件描述符,epoll_wait()便会得到通知
- 调用一次epoll_wait()获得就绪文件描述符时,返回的并不是实际的描述符,而是一个代表就绪描述符数量的值,拿到这些值去epoll指定的一个数组中依次取得相应数量的文件描述符即可,这里使用内存映射(mmap)技术, 避免了复制大量文件描述符带来的开销
当然epoll也有一定的局限性, epoll只有Linux2.6才有实现 ,而其他平台都没有,这和apache这种优秀的跨平台服务器,显然是有些背道而驰了。
简单来说epoll是select的升级版,单进程管理的文件描述符没有最大限制。但epoll只有linux平台可使用。作为跨平台的Apache没有使用。
2.再看一下Apache常用的两种并发策略:
1) perfork模式的工作原理:
当Apache被启动时,Apache会自动创建StartServers个进程,并且尽力将空闲进程数保持在MinSpareServers和MaxSpareServers之间。
如果空闲进程小于MinSpareServers,Apache将会以大约每秒1个的速度新建进程。
如果空闲进程小于MaxSpareServers,Apache将会删除多余的空闲进程,释放服务器资源。
进程数的最大值由MaxClients控制,在Apache1.3中最大只能设置为256,但在Apache2.0中,可以通过在配置开头增加ServerLimit项目来突破256的限制,此时必须MaxClients ≤ ServerLimit ≤ 20000
MaxRequestsPerChild用来控制每个进程在处理了多少次请求之后自动销毁,这个参数可以设置为0表示无限(即不销毁进程)
2) worker模式的工作原理:
由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild线程数,各个线程独立地处理请求。
同样,为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数;而MaxClients设置允许的最大线程总数。
如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。
每个子线程处理服务请求次数由MaxRequestPerChild定义。 缺省的设置值为0,即响应无限此请求。
默认生成3个子进程来处理请求。
两种策略的缺陷:
perfork模式:每一个连接创建一个进程,每个进程内单线程。对于一个负载相对较高的网站来说,256的进程限制是不够的,如果服务器已经达到256的极限,那么接下去的访问就需要排队,这也就是为什么某些服务器负载不高,但是访问却很慢的原因之一。
worker模式:也是多进程处理,也会创建多个进程和多个线程,如果进程数达到管理员设置的阀值,则会拒绝新的请求。
两种模式都会创建多个进程或线程,而每个进程或线程都会为其分配cpu和内存(线程要比进程小的多,所以worker支持比perfork高的并发),并发过大会榨干服务器资源。
3.Nginx的工作原理:
Nginx并不会为每一个的web请求创建新的进程,相反,管理员可以配置Nginx主进程的工作进程的数量(一个常见的做法是为每一个CPU配置一个工作进程)。所有这些进程都是单线程的。
每一个工作进程可以处理数千个并发的请求。它通过一个线程来异步非阻塞的完成了这些工作(epoll),而没有使用多线程的编程模型。
nginx的优势:
采用单线程来异步非阻塞处理请求,不会为每个请求分配cpu和内存资源,节省了大量资源,同时也减少了大量的CPU的上下文切换。所以才使得Nginx支持更高的并发。
Nginx支持比Apache高并发的原因的更多相关文章
- Nginx与Redis解决高并发问题
原文链接:http://bbs.phpchina.com/forum.php?mod=viewthread&tid=229629 第一版产品采用的是Jquery,Nginx,PHP(CI框架) ...
- 面试题:Nginx 是如何实现高并发?常见的优化手段有哪些?
面试题: Nginx 是如何实现并发的?为什么 Nginx 不使用多线程?Nginx常见的优化手段有哪些?502错误可能原因有哪些? 面试官心理分析 主要是看应聘人员的对NGINX的基本原理是否熟悉, ...
- nginx+lua+redis构建高并发应用(转)
nginx+lua+redis构建高并发应用 ngx_lua将lua嵌入到nginx,让nginx执行lua脚本,高并发,非阻塞的处理各种请求. url请求nginx服务器,然后lua查询redis, ...
- Gaea是支持跨平台具有高并发、高性能、高可靠性,并提供异步、多协议、事件驱动的中间层服务框架
Gaea是支持跨平台具有高并发.高性能.高可靠性,并提供异步.多协议.事件驱动的中间层服务框架 Gaea:58同城开源的中间层服务框架 https://github.com/58code/Gaea 中 ...
- 《连载 | 物联网框架ServerSuperIO教程》- 17.支持实时数据库,高并发保存测点数据。附:3.4 发布与版本更新说明。
1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...
- Nginx和Tengine解决高并发和高可用,而非推荐Apache
什么是Nginx 什么是Tengine 看看国内大公司在用Nginx和Tengine吗? 步骤一:进入 https://www.taobao.com/,按F12.可看到 有很多APP对淘宝进行请求. ...
- Nginx+Redis+Ehcache大型高并发高可用三层架构总结
在生产环境中,对于高并发架构,我们知道缓存 是最重要的环节,对于大量的高并发.可以采用三层缓存架构来实现,也就是Nginx+Redis+Ehcache 对于中间件Nginx常来做流量分发,同事ngin ...
- Nginx+tomcat组合实现高并发场景的动静分离和负载均衡方案
简介 Java服务大多是跑在tomcat里,但是众所周知tomcat的并发性能没有优势(tomcat8及以上的版本可能有所改善),所以为了更好的适应高并发的应用场景,我们可以使用tomcat+ngin ...
- 如何快速开发一个支持高效、高并发的分布式ID生成器
ID生成器是指能产生不重复ID服务的程序,在后台开发过程中,尤其是分布式服务.微服务程序开发过程中,经常会用到,例如,为用户的每个请求产生一个唯一ID.为每个消息产生一个ID等等,ID生成器也是进行无 ...
随机推荐
- [SQL] SQL 基础知识梳理(五) - 复杂查询
SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...
- uploadify使用的一些经验总结
说说自己使用uploadify的一波三折的曲折过程: 之所以要选择uploadify,是源于自己先前使用过jQuery官网的上传文件插件,比较难用(页面写的代码比较多,IE下后台回传需要配置格式[不清 ...
- WebComponent魔法堂:深究Custom Element 之 标准构建
前言 通过<WebComponent魔法堂:深究Custom Element 之 面向痛点编程>,我们明白到其实Custom Element并不是什么新东西,我们甚至可以在IE5.5上定 ...
- WebAPI接收JSON参数注意事项
运行环境:ASP.NET 4.5.2. 当我们向GlobalConfiguration.Configuration.MessageHandlers添加一个DelegatingHandler派生类后,很 ...
- GridView详细介绍
GridView控件的属性 表10.6 GridView控件的行为属性属性描述AllowPaging指示该控件是否支持分页.AllowSorting指示该控件是否支持排序.AutoGenerateCo ...
- js给DropdownList赋值
", "model": "APOLLO M/B1"}]; ; i < row.length; i++) { var addOption = do ...
- C#中怎样实现序列化和反序列化
我们想要将数据进行持久化的操作的话,也就是将数据写入到文件中,我们在C#中可以通过IO流来操作,同时也可以通过序列化来操作,本人是比较推荐使用序列化操作的 因为我们如果想要将一个对象持久化到文件中 如 ...
- Gradle project sync failed
在Android Studio中运行APP时出现了以下错误: gradle project sync failed. please fix your project and try again 解决的 ...
- Python VS PHP 基础语法
这几天在学习Python,鄙人平时学习中为了方便记忆和更好的比较与理解语言二者之间在某些情况的优劣性,所以花了点时间,整理了一下 Python 和 PHP 常用语法的一些区别. 一.大小写 PHP: ...
- jqGrid插件getCol方法的一个改进
jgGrid插件是非常常用的一个基于jQuery的表格插件,功能非常强大.我最近也频繁使用.但是这个插件也有一些不够完善的地方.比如这个getCol方法. getCol方法接受三个参数 colname ...