阿里云
为了无法计算的价值
打开APP
阿里云APP内打开
学习中心> Linux Web服务器Nginx搭建与配置> 正文

Linux Web服务器Nginx搭建与配置

5课时 |
13444人已学 |
免费
课程介绍

Nginx是一个高性能的Web和反向代理服务器, Netcraft在2019年4月发布的Web服务器调查报告,排名前三的是 Nginx市场份额排名第一位。

Nginx具有有很多非常优越的特性:

  • 作为Web服务器:相比Apache,Nginx使用更少的资源,支持更多的并发连接,体现更高的效率,能够支持高达 50,000个并发连接数的响应。
  • 作为负载均衡服务器:Nginx既可以在内部直接支持Rails和PHP,也可以支持作为HTTP代理服务器对外进行服务。Nginx用C编写, 不论是系统资源开销还是CPU使用效率都比Perlbal要好的多。
  • 作为邮件代理服务器: Nginx同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器)。

 

nginx 介绍及安装

内容介绍

一、I/O 模型

二、Nginx 介绍

 

一、I/O 模型

(1)Httpd MPM

httpd MPM :

  • prefork :进程模型,两级结构,一个主进程 master 负责若干个生成子进程,每个子进程负责响应一个请求。
  • worker :线程模型,三级结构,主进程 master 负责生成子进程,每个子进程负责生成多个线程, 当用户发起请求,由每个线程响应一个请求。
  • event :线程模型,三级结构,主进程 master 负责生成子进程,

一个监控线程,回收未被利用的线程,每个子进程响应多个请求。

httpd的程序非常稳定,相对来讲在一些传统的公司用web服务的话很多都是httpd,但是对于互联网公司来讲,往往会产生一些不胜任的情况,比方说当并发量达到比较大的时候,连接数过万的时候,其性能就会急剧下降,nginx据说可以应付达到三万以上的并发,主要取决于IO模型

(2)I/O 介绍

I/O:

  • 网络 IO : 本质是 socket 读取。对网络上的数据进行传输的时候,他本质上也算是一种IO,因为在网络编程的时候,实现的socket通讯之间无非也是读和写的机制,在 Linux 之中,一切皆文件,所以你在网络中发送文件的时候是发送到 socked 文件中,通过 socked 转发到远程程序,也是用 socked 接收。
  • 磁盘 IO :

每次IO ,都要经由两个阶段:

  • 第一步:将数据从磁盘文件先加载至内核内存空间(缓冲区) ,等待数据准备完成,时间较长
  • 第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短

一般情况下的通讯过程:

当服务器收到远程通信http的请求,希望得到一个 html 文件,那这个请求会到达网卡,nginx 线程接收收到请求。而 index 文件在物理磁盘上,nginx 是一个进程是工作在用户空间的,用户空间的进程是不能返回硬件的,发请求到kernel,所以需要通过 kernel 去访问磁盘,由 kernel 获取到 kernel 缓冲区,再复制到 nginx 缓冲区,来实现数据最终的得到获取,

如下图

(3) I/O 模型

同步/异步:关注的是消息通信机制

  • 同步: synchronous ,调用者等待被调用者返回消息,才能继续执行
  • 异步: asynchronous ,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态 

阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态

  • 阻塞: blocking ,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起
  • 非阻塞: nonblocking ,指IO操作被调用后立即返回给用户一个状态值 , 无需等到IO操作彻底完成,最终的调用结果返回之前,调用者不会被挂起

I/O 模型:

  • 阻塞型、非阻塞型、复用型、信号驱动型、异步

(4) 同步阻塞IO模型

  • 同步阻塞IO模型是最简单的IO模型,用户线程在内核进行IO操作时被阻塞
  • 用户线程通过系统调用 read 发起 IO 读操作,由用户空间转到内核空间。内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成 read 操作
  • 用户需要等待read将数据读取到 buffer 后 ,才继续处理接收的数据。整个IO请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对 CPU 的资源利用率不够
  • 在实际工作中内核和用户进程那个效率高,相对影响用户体验,通常来讲,用户是访问应用程序的,不是访问内核的,内核是为应用程序提供服务的所以希望应用程序访问更快,用户感受更好,话句话说一件事是应用程序做还是内核做,如果应用程序做的事多了,自然对用户响应请求就更慢了,内核多做点减轻了应用程序的事那对用户响应请求就更快,延申出来希望内核做的事多一些,应用程序少做一些,这样应用程序就可以接收更多的用户请求。

(5) 同步非阻塞 IO 模型

同步的意思是去访问一个资源,事情做没做完不清楚,只有自己去看。所以当要得到一个资源的时候,发一个请求由内核来完成,内核系统调用recvfrom来完成,但是是否已完成并不知道,所以只能一次次的系统调用去问,非阻塞意味着进程发一个指令给内核,希望他得到一个数据,还可以干点别的事但又由于是同步,不清楚对方做好准备没有,一直问直到数据从磁盘放到内核为止,等一会将数据从内核拷贝到用户空间,才通知整个结束。

在磁盘文件复制到内核过程中,用户是并不了解的,他只有不断的轮询。

  • 用户线程发起IO请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据到达后,才真正读取到数据,继续执行。即"轮询”机制
  • 整个IO请求的过程中,虽然用户线程每次发起IO请求后可以立即返回,但是为了等到数据,仍需要不断地轮询、重复请求,消耗了大量的 CPU 的资源
  • 是比较浪费 CPU 的方式,一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性

(6) I/O 多路复用模型

不用每个进程都要和内核打交道,直接找一个专门的代理select,但进程会受阻与select,发出请求到内核,等待数据从内核复制到用户空间,将数据分成了两部分,第一个阶段是用户进程阻塞在select,第二个阶段是用户进程等待数据从内核空间复制用户空间。实际上也是总阻塞状态。虽然总体性能未提高,但有select可以面对很多用户的请求。

  • 多个连接共用一个等待机制,本模型会阻塞进程,但是进程是阻塞在 select 或者 poll 这两个系统调用上,而不是阻塞在真正的 IO 操作上
  • 用户首先将需要进行 IO 操作添加到 select 中,继续执行做其他的工作(异步) , 同时等待 select 系统调用返回。当数据到达时, IO 被激活,select 函数返回。用户线程正式发起 read 请求,读取数据并继续执行。
  • 从流程上来看,使用 select 函数进行 IO 请求和同步阻塞模型没有太大的区别,甚至还多了添加监视 IO ,以吸调用 select 函数的额外操作,效率更差。并且阻塞了两次,但是第一次阻塞在 select  上时,  select 可以监控多个IO上是否已有IO操作准备就绪,即可达到在同一个线程内同时处理多个IO请求的目的。而不像阻塞IO那种,一次只能监控一个IO
  • 虽然上述方式允许单线程内处理多个IO请求,但是每个IO请求的过程还是阻塞的(在select函数上阻塞) , 平均时间甚至比同步阻塞IO模型还要长。如果用户线程只是注册自己需要的IO请求,然后去做自己的事情,等到数据到来时再进行处理,则可以提高 CPU 的利用率
  • IO多路复用是最常使用的IO模型,但是其异步程度还不够“彻底”, 因它使用了会阻塞线程的select系统调用。因此IO多路复用只能称为异步阻塞IO模型,而非真正的异步IO

多路 I/O 复用

IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,就通知该进程

IO多路复用适用如下场合 :

  • 当客户端处理多个描述符时( -般是交互式输入和网络套接口) , 必须使用I/O复用
  • 当一个客户端同时处理多个套接字,多个请求时,此情况可能的但很少出现
  • 当一个 TCP 服务器既要处理监听套接字,又要处理已连接套接字,一般也要用到I/O复用
  • 当一个服务器即要处理 TCP ,又要处理 UDP,一般要使用I/O复用
  • 当一个服务器要处理多个服务或多个协议,一般要使用I/O复用

(7) 信号驱动 IO 模型

具有更多的异步特性,就是调用者不需要主动问被调用者,比如当磁盘文件读取到内核当中时,数据还未得到,但进程仍可继续执行,或者响应其他用户的请求,直到磁盘文件读取到内核当中后,将数据从内核拷贝到用户空间中,但这个过程中需要等待,换句话说就是有一部分实现了异步,一部分仍是同步,意味着信号驱动IO模型将数据分成了一半阻塞不阻塞状态,效率提高了不少,因为将磁盘文件拷贝到内核空间上是最费时间的,而信号驱动IO模型可以将这时间自由分配。

  • 信号驱动 IO : signal-driven I/O
  • 用户进程可以通过 sigaction 系统调用注册一个信号处理程序,然后主程序可以继续向下执行,当有IO操作准备就绪时,由内核通知触发一个 SIGIO 信号处理程序执行,然后将用户进程所需要的数据从内核空间拷贝到用户空间
  • 此模型的优势在于等待数据报到达期间进程不被阻塞。用户主程序可以继续执行,只要等待来自信号处理函数的通知
  • 该模型并不常用