纵有疾风起
人生不言弃

Nginx的前世今生

一、Nginx的诞生

      当年啊有个技术困难叫C10K问题,就是如何解决10万个客户端的并发请求问题。然后有个俄罗斯大牛某某某,在02年使用C语言搞了个东东声称可以处理每天5亿请求,然后还开源了,这个东东就是叫Nginx(Nginx:”engine x” )的一个Http服务器及反向代理服务器。还有电子邮件(IMAP/POP3)功能啥的。据说可以承受5万并发链接,其实我4.9万就够用了。

二、为什么使用Nginx?

原因一、  IO多路复用epoll

1、当文件描述符fd就绪,采用系统的回调函数之间将fd放入,效率更高

2、最大连接数无限制    cat /proc/sys/fs/file-max

原因二、  轻量级 、模块扩展

功能模块少, 代码模块化,因此除了反向代理和资源缓存等核心功能外,尽可能地避免添加不必要的功能模块。

Nginx有许多优秀的标准库和第三方模块,比如流量和连接监控和限制、图像格式转换等等。

如果要添加新模块的话,必须将整个程序重新编译。虽然这样不如Apache HTTP的动态加载来得方便,但是可以保证运行效率的最大化和占用资源的最小化。

原因三、 CPU亲和 affinity

把cpu核心和nginx 工作进程绑定,把每个worker进程固定在一个cpu上执行,减少切换cpu的cache miss,获得更好性能 。

原因四、  sendfile

0拷贝传输模式,通过内核空间之间传输

其实还有很多别的优点

总之:

高速、轻量、高性能等优点集于一身

所以:

Nginx在近些年迅速发展并不断扩大市场份额,甚至在最近其市场份额一举超过微软的IIS,跃身到第二位,仅次于Apache。

但是由于其高性能的特点,尤其适用于高流量网站,在全球前 10,000个站点中的市场份额为58.4%,稳居第一。

三、Nginx的应用场景

1、 http服务器。提供http服务,可以做网页静态服务器。

2、 虚拟主机。可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。

  • 基于端口的,不同的端口
  • 基于域名的,不同域名

3、 反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。

四、其它特点

1、处理动态资源

Nginx很擅长负载均衡和处理HTML文件和图片等静态资源,但是除了SSI(Server Side Include)技术以外基本不能够自己动态地生成资源。

这时,其实我们可以通过UNIX Domain Socket来让其他进程处理并返回对应的动态资源。如果该进程位于其他机器上,则可以通过TCP来进行通信。

特别地,对于和PHP程序之间的通信可以使用FastCGI,对于Python可以使用uWSGI,对于Ruby on Rails可以使用Phusion Passenger。对于Dot Net 以后再细说

2、性能秘诀——事件驱动

Nginx之所以能同时处理大量的请求,原因在于它采用了十分巧妙的事件驱动机制。

作为一个Web服务器,要同时处理多个请求,不可避免地要面对这么一个问题,如何同时处理像磁盘和网络等等的I/O请求,即如何实现I/O复用。

为了解决该问题,操作系统在很久之前就开始提供诸如“select”、“poll”等系统调用。Apache HTTP的多处理模块(MPM,multi-processing module)就会用到这些系统调用。

但是,select/poll为了识别出哪些文件或者socket已经准备就绪,必须将所有已注册的文件描述符(fd)一个个地检查一遍。如果注册列表越长,那么每次的扫描所需的时间也越长。

而Nginx的I/O复用机制使用的是“epoll”这个基于事件驱动的系统调用。因为epoll会在系统内核管理和监听这些文件描述符(fd),并自动把就绪的加入到Ready队列当中。

所以,程序只需在需要时往Ready队列中取出一个进行处理即可,而不用切换到内核态,然后一个个地检查,然后又切换回用户态。

这样,无论需要注册监听的I/O有多少,都不会影响程序的运行效率。

为了避免select/poll带来的线性增长的负担,Apache HTTP必须将这些IO分散到各个进程/线程中处理,这样势必会造成占用内存的增长。

但是,Nginx可以通过利用“epoll”,保证可以使用一个进程/线程完成所有请求的处理,这样可以大大减少内存的占用,从而使应对上万并发请求成为可能。

 

相关知识点


①、代理服务器:

一般是指局域网内部的机器通过代理服务器发送请求到互联网上的服务器,代理服务器一般作用在客户端。应用比如:GoAgent,FQ神器.    一个完整的代理请求过程为:客户端首先与代理服务器创建连接,接着根据代理服务器所使用的代理协议,请求对目标服务器创建连接、或者获得目标服务器的指定资源。 Web代理(proxy)服务器是网络的中间实体。 代理位于Web客户端和Web服务器之间,扮演“中间人”的角色。HTTP的代理服务器即是Web服务器又是Web客户端。
代理服务器是介于客户端和Web服务器之间的另一台服务器,有了它之后,浏览器不是直接到Web服务器去取回网页而是向代理服务器发出请求,信号会先送到代理服务器,由代理服务器来取回浏览器所需要的信息并传送给你的浏览器。

②、正向代理 

正向代理是一个位于客户端和原始服务器直接的服务器,代理服务器对于客户端是可见的,为了从原始服务器取得内容,客户端需要先进行代理配置,然后向代理服务器发送请求并制定目标,之后代理服务器其访问指定的目标服务器并把响应内容返回给客户端。

Nginx的前世今生插图

典型的应用比如VPN。我们通过连接VPN输入登录名密码,然后就可以访问google了。

它一般有着几个作用:

  1. FQ
  2. 加速访问
  3. Cache作用
  4. 客户端授权访问

③、反向代理:

反向代理中,客户端是不知道反向代理服务器的存在的,也不需要进行特别的设置,因为反向代理服务器对于客户端而已就像原始服务器一般。
客户端向反向代理的命名空间(name-space)中的内容发生普通请求,然后反向代理服务器将判断向哪一个原始服务器转交(非转发)请求,并将获得你 内容返回给客户端。

  反向代理的作用:

  1. 保护和隐藏原始服务器

Nginx的前世今生插图1

2.负载均衡

Nginx的前世今生插图2

这时反向代理服务器就是一个前置机,根据流量和原始服务器的负载压力对请求进行动态调整。

 

④、文件描述符:

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。

⑤、内核态:

CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序

⑥、用户态:

     只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取

⑦、为什么要有用户态和内核态

由于需要限制不同的程序之间的访问能力, 防止他们获取别的程序的内存数据, 或者获取外围设备的数据, 并发送到网络, CPU划分出两个权限等级 — 用户态 和 内核态

⑧、用户态与内核态的切换

所有用户程序都是运行在用户态的, 但是有时候程序确实需要做一些内核态的事情, 例如从硬盘读取数据, 或者从键盘获取输入等. 而唯一可以做这些事情的就是操作系统, 所以此时程序就需要先操作系统请求以程序的名义来执行这些操作.

这时需要一个这样的机制: 用户态程序切换到内核态, 但是不能控制在内核态中执行的指令

这种机制叫系统调用, 在CPU中的实现称之为陷阱指令(Trap Instruction)

他们的工作流程如下:

  1. 用户态程序将一些数据值放在寄存器中, 或者使用参数创建一个堆栈(stack frame), 以此表明需要操作系统提供的服务.
  2. 用户态程序执行陷阱指令
  3. CPU切换到内核态, 并跳到位于内存指定位置的指令, 这些指令是操作系统的一部分, 他们具有内存保护, 不可被用户态程序访问
  4. 这些指令称之为陷阱(trap)或者系统调用处理器(system call handler). 他们会读取程序放入内存的数据参数, 并执行程序请求的服务
  5. 系统调用完成后, 操作系统会重置CPU为用户态并返回系统调用的结果
未经允许不得转载:起风网 » Nginx的前世今生
分享到: 生成海报

评论 抢沙发

评论前必须登录!

立即登录