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的前世今生的更多相关文章

  1. nginx+gunicorn/uwsgi+python web 的前世今生

    我们在部署 flask.django 等 python web 框架时,网上最多的教程就是 nginx+gunicorn/uwsgi 的部署方式,那为什么要这么部署呢,本文就来系统地解释这个问题. 必 ...

  2. Tomcat负载均衡、调优核心应用进阶学习笔记(二):Tomcat前世今生、安装、配置文件详细说明、tomcat应用程序部署、webapp 体系结构、tomcat运行方式

    文章目录 Tomcat前世今生 安装 配置文件详细说明 tomcat应用程序部署 webapp 体系结构 tomcat运行方式 Tomcat前世今生 java体系: 1 java程序设计语言 2 ja ...

  3. Containerd 的前世今生和保姆级入门教程

    原文链接:https://fuckcloudnative.io/posts/getting-started-with-containerd/ 1. Containerd 的前世今生 很久以前,Dock ...

  4. accept_mutex与性能的关系 (nginx)

    注:运行环境CentOS 6+   背景      在对启动了20个worker的nginx进行压力测试的时候发现:如果把配置文件中event配置块中的accept_mutex开关打开(1.11.3版 ...

  5. nginx配置反向代理或跳转出现400问题处理记录

    午休完上班后,同事说测试站点访问接口出现400 Bad Request  Request Header Or Cookie Too Large提示,心想还好是测试服务器出现问题,影响不大,不过也赶紧上 ...

  6. 【大型网站技术实践】初级篇:借助Nginx搭建反向代理服务器

    一.反向代理:Web服务器的“经纪人” 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从 ...

  7. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  8. Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境

    首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...

  9. nginx+php的使用

    原文来自:windows下配置nginx+php环境 按照他的步骤走,亲测可用! 但是这里他后面说的根目录可能有些人有点懵. 其实在设置的时候就设置了: 网站根目录就是www这个目录,如果没创建请自行 ...

随机推荐

  1. 检测U盘插入、拨出状态

    头文件 #include <Dbt.h> 关键代码: LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LP ...

  2. Qt QSpinBox 和 QDoubleSpinBox

    展示一个效果: QDoubleSpinBox跟QSpinBox类似,只是多了一个decimal.

  3. C# 数组在内存中的存储

    C# 数组是引用类型,那么在内存中是如何存储的呢? 在VS中调试C#程序,如何查看内存.寄存器.反汇编 在这篇文章里看到了如何在VS 中查看内存 先断点打在数组创建后语句那里,点debug->W ...

  4. supervisor 从安装到使用

    (转)https://www.jianshu.com/p/3658c963d28b 一.安装 源码安装 先下载最新的supervisor安装包:https://pypi.python.org/pypi ...

  5. Jmeter二次开发

    Jmater函数扩展的步骤1. 导入Jmeter源码,或使用maven项目,引入依赖的jar包 2. 继承AbstractFunction,实现自定义Function 3. 继承JMeterTestC ...

  6. FileOutputSream文件字节输出流

    1.FileOutputSream文件字节输出流:  输入--写出--使用:  输出--写入--存储: 写出写入是对硬盘而言: 其中,OutputStream为所有类型的字节输出流的超类: FileO ...

  7. IP通信基础学习第四周(上)

    IP地址现在由因特网名字与号码指派公司ICANN进行分配,它是标志一个主机(或路由器)和一条链路的接口,其编址方法有:分类的IP地址.子网的划分.构成超网. 分类两级IP地址可以记为:IP::={&l ...

  8. oracle 两张关联表执行更新update

    UPDATE T_ASN_DTL ad1 SET ad1.cf03=( SELECT ac.TH003 FROM "T_ASN_DTL_copy" ac WHERE ac.udf0 ...

  9. babel 7.x 和 webpack 4.x 配置vue项目

    很偶然的今天想开个自己的小项目,记录一下最近项目工程上实现的一个小交互.按照之前运行非常流畅的配置走一遍,打包遇到各种坑.只好根据命令行的报错逐个排查,发现babel升级了一个大版本,已经到7.x了. ...

  10. 用JavaScript+css制作下拉式菜单

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...