nginx的前世今生
Nginx最初的设计是称为一个http服务器,一个能够解决C10K问题的http服务器。
那么问题来了,什么是C10K呢?C10K问题即(单机10万个并发链接问题),这个概念最早是由Dan Kegel发布于其个人站点。
我们说互联网的基础是网络通信对吗?而早期的互联网可以说是一个小群体的集合。互联网还不够普及,用户也不多,一台服务器同时在线100个用户估计在当时已经是大型网站了,所以并不存在C10K的难题。互联网的爆发期应该在www网站,浏览器,雅虎出现后。
web1.0的出现,互联网的大部分使用场景是下载一个HTML页面,用户在浏览器中查看网页上的信息,这个时期也不存在C10K的问题。
web2.0时代的到来,一方面是普及率大大提升,用户集群倍数增长,另一方面互联网不在是单纯的浏览万维网网页上的信息,逐渐开始进行交互,而且应用程序的逻辑也变的更复杂了,从简单的表单提交提交,到即时通信和在线实时互动,C10K的问题出现了。因为每一个用户都需要与服务器保持TCP链接才能进行实时的数据交互。
最初的服务器都是基于进程/线程模型的,新到来的一个TCP链接,就需要分配1个进程(或者线程)。而进程又是操作系统最昂贵的资源,一台机器无法创建很多个进程。如果是C10K就要创建1万个进程,那么单机而言操作系统是无法承受的,如果采用分布式系统,维持1亿的在线用户需要10万台服务器,成本巨大。
这些局限和问题最早被Dan Kegel进行了归纳和总结,并首次系统分析并提粗解决方案,后来这种普遍的网络网络现象和技术局限被成为C10K。
解决以上问题呢,有两种思路:
一种是对于每一个链接处理分配一个独立的进程/线程;另一个思路是用同一个进程/线程来同时处理若干链接。
创建的进程线程多了,数据拷贝频繁(缓存I/O、内核将数据拷贝到用户进程空间、阻塞), 进程/线程上下文切换消耗大, 导致操作系统崩溃。
● 实现方式2:select要解决上面阻塞的问题,思路很简单,如果我在读取文件句柄之前,先查下它的状态,ready 了就进行处理,不 ready 就不进行处理,这不就解决了这个问题了嘛?于是有了 select 方案。用一个 fd_set 结构体来告诉内核同时监控多个文件句柄,当其中有文件句柄的状态发生指定变化(例如某句柄由不可用变为可用)或超时,则调用返回。之后应用可以使用 FD_ISSET 来逐个查看是哪个文件句柄的状态发生了变化。这样做,小规模的连接问题不大,但当连接数很多(文件句柄个数很多)的时候,逐个检查状态就很慢了。因此,select 往往存在管理的句柄上限(FD_SETSIZE)。同时,在使用上,因为只有一个字段记录关注和发生事件,每次调用之前要重新初始化 fd_set 结构体。
intselect(intnfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,structtimeval *timeout);
实现小结:有连接请求抵达了再检查处理。
问题归纳:句柄上限+重复初始化+逐个排查所有文件句柄状态效率不高。
● 实现方式3:poll 主要解决 select 的前两个问题:通过一个 pollfd 数组向内核传递需要关注的事件消除文件句柄上限,同时使用不同字段分别标注关注事件和发生事件,来避免重复初始化。
实现小结:设计新的数据结构提供使用效率。
问题归纳:逐个排查所有文件句柄状态效率不高。
● 实现方式4:epoll既然逐个排查所有文件句柄状态效率不高,很自然的,如果调用返回的时候只给应用提供发生了状态变化(很可能是数据 ready)的文件句柄,进行排查的效率不就高多了么。epoll 采用了这种设计,适用于大规模的应用场景。实验表明,当文件句柄数目超过 10 之后,epoll 性能将优于 select 和 poll;当文件句柄数目达到 10K 的时候,epoll 已经超过 select 和 poll 两个数量级。
实现小结:只返回状态变化的文件句柄。
问题归纳:依赖特定平台(Linux)。
nginx正是基于这样的开发理念,使得其有占用内存少,并发能力强的特性。
nginx的前世今生的更多相关文章
- nginx+gunicorn/uwsgi+python web 的前世今生
我们在部署 flask.django 等 python web 框架时,网上最多的教程就是 nginx+gunicorn/uwsgi 的部署方式,那为什么要这么部署呢,本文就来系统地解释这个问题. 必 ...
- Tomcat负载均衡、调优核心应用进阶学习笔记(二):Tomcat前世今生、安装、配置文件详细说明、tomcat应用程序部署、webapp 体系结构、tomcat运行方式
文章目录 Tomcat前世今生 安装 配置文件详细说明 tomcat应用程序部署 webapp 体系结构 tomcat运行方式 Tomcat前世今生 java体系: 1 java程序设计语言 2 ja ...
- Containerd 的前世今生和保姆级入门教程
原文链接:https://fuckcloudnative.io/posts/getting-started-with-containerd/ 1. Containerd 的前世今生 很久以前,Dock ...
- accept_mutex与性能的关系 (nginx)
注:运行环境CentOS 6+ 背景 在对启动了20个worker的nginx进行压力测试的时候发现:如果把配置文件中event配置块中的accept_mutex开关打开(1.11.3版 ...
- nginx配置反向代理或跳转出现400问题处理记录
午休完上班后,同事说测试站点访问接口出现400 Bad Request Request Header Or Cookie Too Large提示,心想还好是测试服务器出现问题,影响不大,不过也赶紧上 ...
- 【大型网站技术实践】初级篇:借助Nginx搭建反向代理服务器
一.反向代理:Web服务器的“经纪人” 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从 ...
- 【调侃】IOC前世今生
前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...
- Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境
首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...
- nginx+php的使用
原文来自:windows下配置nginx+php环境 按照他的步骤走,亲测可用! 但是这里他后面说的根目录可能有些人有点懵. 其实在设置的时候就设置了: 网站根目录就是www这个目录,如果没创建请自行 ...
随机推荐
- 搭建apache本地服务器·Mac
1. 打开终端,开启Apache: //开启apache: sudo apachectl start //重启apache: sudo apachectl restart //关闭apache: su ...
- java操作对比两个字符串,将差异数据提取出来
记录瞬间 在实际的工作中,需要解决生成两次字符串结果进行对比的问题,将存在差异的字符串直接给出来. 当然,前提是需要将对比的两次结果,进行前期处理 比如: a_str = "@com/ene ...
- Java类型信息之RTTI
软件工程的一个核心问题就是软件的复用和扩展.面向对象思想通过封装,继承,派生等机制有效地解决了这个问题.但需求总是变幻莫测,不可琢磨,在面向对象这栋恢宏的大厦旁,还漂浮着一朵乌云,从而导致了RTTI的 ...
- BeyondCompare使用一段时间后会因“许可证密钥已被撤销:3281-0350“而无法使用
解决方式: 1.用任意文本编辑软件打开“C:\Users\[Your User Name]\AppData\Roaming\Scooter Software\Beyond Compare 3\BCSt ...
- 游戏引擎——cocos2d-x
Cocos2d-x是一个开源的移动2D游戏框架,MIT许可证下发布的.这是一个C++ Cocos2d-iPhone项目的版本.Cocos2d-X发展的重点是围绕Cocos2d跨平台,Cocos2d-x ...
- 【Spark-SQL学习之二】 SparkSQL DataFrame创建和储存
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 scala-2.10.4(依赖jdk1.8) spark ...
- Spring的事务
事务:事务指的是逻辑上的一组操作,这组操作要么都成功,要么都失败. Transaction事务的四大特性ACID: 1.Atomicity原子性 事务的操作要么都成功,要么都不做,只要有一个失败,就会 ...
- Mysql+jsp连接记录
1.下载tomacat 2.jsp项目的创建 3.tomacat和jsp挂钩起来 4.mysql下载 5.mysql可视化 6.随便写下sql语句 7.下载jdbc驱动 8.在jsp里面写 over!
- HTTP首部概览
HTTP首部概览: . Accept:告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type. 2. Accept-Charse ...
- STM32时钟
https://blog.csdn.net/qq_29350001/article/details/81409693 这是个大佬讲的 F429有5个时钟源,HSI,HSE,LSI,LSE;PLL; 对 ...