Nginx架构初探

157 阅读9分钟
原文链接: click.aliyun.com

Nginx的五大模块

核心模块

  • 提供Nginx的核心功能,主要包括两类支持

    • 一类是主体功能:进程管理,权限控制,错误日志记录...
    • 一类是响应请求事件:事件驱动机制,正则表达式解析等...

标准的HTTP模块

http_bz1
http_bz3
http_bz2

可选HTTP模块

http_kx1
http_kx2
http_kx3

邮件服务模块

  • nginx并不会默认的编译邮件模块
  • 相关的邮件服务模块

    • ngx_mail_core_module
    • ngx_mail_pop3_module
    • ngx_mail_imap_module
    • ngx_mail_smtp_module
    • ngx_mail_auth_module
    • ngx_mail_proxy_module
    • ngx_mail_ssl_module

      • 上面模块完成了邮件服务的主要功能,包括对pop3,IMAP,SMTP协议的支持.对身份认证,邮件代理和SSL安全服务的提供

第三方模块

  • 第三方的就有很多了..

nginx的web请求处理机制

  • 服务器必须有能力同时为多客户端提供服务,一般来说完成并行处理请求工作有三种方式可供选择

    • 多进程方式

      • 多进程是指:服务器每当接收到一个客户端时,就由服务器主进程生成一个子进程来和该客户端交互
      • 优点:设计实现简单,各个进程之间相互独立,处理客户端请求的过程彼此不受到干扰,当程序退出,占用资源会被回收
      • 缺点:操作系统生成子进程需要进行内存复制等操作,产生的开销太大
    • 多线程方式

      • 多线程是指:服务器接收到客户端时,会由服务器主进程派生一个线程和该客户端交互
      • 优点:线程的创建远比进程小
      • 缺点:多线程位于同一进程中,可以同时访问同样的内存空间,彼此之间相互影响,编程难度增加
    • 异步方式

      • 在异步机制中,发送方发出一个请求后,不等待接收方响应这个请求,就继续发送下一个请求,所有来自发送方的请求形成一个队列,接收方处理完成后通知发送方
      • 优点:简单、可靠,适用于面向字符的、低速的异步通信场合
      • 缺点:通信开销大,每传输一个字符都要额外附加2~3位,通信效率比较低。

Nginx服务器如何处理请求

  • Nginx结合多进程机制和异步机制对外提供服务,异步机制使用的是异步非阻塞方式

    • Nginx的主进程和多个工作进程(worker process),其中所有的工作进程都用于接收和处理客户端的请求,预先生成多个工作进程等待处理客户端请求
    • 每个worker process都是用了异步非阻塞方式,可以处理多个客户端请求,当某个worker process接收到客户端的请求以后,调用IO进行处理,如果不能立即得到结果,就去处理其他的请求,期间客户端也无须等待,当IO调用返回结果后,就会通知worker process,worker process得到通知后,就会挂起当前处理的事务,去响应客户端请求

Nginx服务器的事件处理机制

  • 上述的处理请求的过程中会产生一个疑问: IO调用返回后是如何将自己的状态通知到worker process呢?

    • 方案一: 就是每隔一段时间就去检查一下IO状态,但是这样会浪费资源
    • 方案二:利用事件驱动模型:select/poll/epoll/kqueue,他们提供了一种机制,让进程可以同时处理多个并发请求,不用关心IO调用的具体状态,IO调用完全由事件驱动模型来管理,时间准备好之后就通知工作进程事件已经就绪

事件驱动模型

  • 事件驱动就是在持续事务管理过程中,由当前时间点上出现的事件引发的调动可用资源执行相关任务,解决不断出现的问题,防止事务堆积的一种策略.
  • 事件驱动模型一般是由三部分基本单元组成

    • 事件收集器:专门收集所有时间,比如点击事件
    • 时间发送器:将收集器收集到的事件分发到目标对象中
    • 时间处理器:目标对象就是事件处理器所处的位置.负责具体事件的响应工作
select库
  • 各个版本的linux和windows都支持的库
  • select顾名思义 是查询的意思,所以这个库的实现方式也是去轮询所有的事件看看是否有事件发生,当数据量小时候还行,数据量激增性能就会下降
  • nginx如果没有指定驱动模型库,自动编译该库
  • 使用--with-select_module--without-select_module来指定是否编译该库
poll库
  • windows不支持
  • 是select的优化实现
  • 使用--with-poll_module--without-poll_module来指定是否编译该库
epoll库
  • epoll库是将事件描述符添加关注事件之后,并把它添加到内核的事件列表中取,时间的发生由内核来通知epoll库,然后epoll在进行事件处理
  • 事件描述符:类似读改写之类的监听
  • 在事件描述符上设置所关注的事件
rtsig模型
  • 工作进程会通过系统内核建立一个rtsig队列用于存放标记事件发生的信号,每个事件发生时,系统内核就会产生一个信号存放到rtsig队列中等待工作进程的处理,最大长度为1024.这个参数是可以更改的
  • 当溢出时,而调用poll库处理未处理的事件,直到队列全部清空,然后再次启动rtsig模型,以防新的溢出发生

Nginx的进程

  • 主进程Master process

    • 读取配置文件并验证有效性
    • 建立绑定和关闭Socket
    • 按配置生成管理和结束工作进程
    • 接受外部指令:比如重启
    • 不中断服务,实现平滑重启和升级
    • 开启日志文件,获取文件描述符
    • 编译和处理Perl脚本
  • 工作进程Worker process

    • 接收客户端请求
    • 将请求依次送入各个功能模块进行过滤处理
    • IO调用获取响应数据
    • 有后端服务器通信,接收后端服务器处理结果
    • 数据缓存,访问缓存索引,查询和调用缓存数据
    • 发送请求结果,响应客户端请求
    • 接收主程序指令:重启...
  • 缓存索引重建及管理进程(Cache Loader & Cache Manager)

    • 架构图中的Cache模块,主要由缓存索引重建和缓存索引管理两类进程完成工作,缓存索引重建进程是在Nginx服务启动一段时间之后由主进程生成,默认是1分钟.在缓存元数据重建完成后就自动退出.缓存索引管理进程一般存在与主进程的整个生命周期
    • 缓存索引重建主要工作:根据本地磁盘上的缓存文件在内存中建立索引元数据库,进程启动时,会检查本地缓存元数据是否正确并更新索引元数据库
    • 缓存索引管理主要负责在索引元数据更新完成后,对元数据是否过期做出判断
进程交互
  • 主进程和工作进程交互依赖于管道机制channel,交互的准备工作都是在工作进程生成时完成的
  • Master-Worker交互

    • 工作进程由主进程生成,服务器启动以后,主进程根据配置生成特定数量的工作进程,然后建立一张全局的工作进程表用于存放当前未退出的所有工作进程
    • 主进程生成工作进程并将其进入工作进程表中,并建立一个单向管道向工作进程发送指令等信息
    • 主进程与外界也是由信号进程通信,当接收到信号后,他通过单向管道给工作进程发送信息,工作进程接收并采取相应措施,这样完成了Master-Worker的交互
  • Worker-Worker交互

    • Worker到Master的交互的实现与Master到Worker交互基本一致.
    • 为了达到Worker到Worker之间的交互,W1首先在主进程给他的进程信息中找到W2的进程ID,然后将质量写入指向W2,这样就完成了Worker-Worker交互
Run Loops事件处理循环模型
  • Run Loops指进程内部用来不断得调配工作,对事件进行循环处理的一种模型
  • Nginx服务器在工作进程中实现了此事件处理循环模型的使用,用来处理客户端发来的请求时间,实现包含了对输入时间繁杂的响应和处理过程,并且处理过程是基于异步任务处理的
  • 当磁盘没有足够的性能处理大量IO时,工作进程仍然可能因为磁盘读写调用而阻塞,进而导致客户端请求超时失败等问题

异步方式的一些概念

同步机制和异步机制描述通信模式的概念

同步机制

  • 是指发送方发送请求后,需要等待接收到接收方发回的响应后,才接着发送下一个请求
  • 所有的请求在服务器端得到同步,发送方和接收方对请求的处理步调是一致的

异步机制

  • 发送方发出一个请求后,不等待接收方响应这个请求,就继续发送下个请求.
  • 所有来自发送方的请求形成一个队列,接收方处理完后通知发送方

阻塞和非阻塞从来描述进程处理调用的方式

阻塞方式

  • 调用结果返回之前,当前线程从运行状态被挂起,一直等到调用结果返回之后才会进入就绪状态,获取CPU后继续执行

非阻塞方式

  • 如果调用结果不能立马返回,当前线程也不会挂起,而是立即返回执行下一个调用

同步阻塞

  • 发送方向接收方发生请求后一直等待响应,在返回结果之前不能干别的,比如超市结账

同步非阻塞

  • 发送方向接收方发起请求后,接收方如果不能立马返回结果,那么就去做别的事,当请求结果出现后,再去响应发起方,期间发起方一直处于等待

异步阻塞

  • 发送方向接收方发起请求后,发送方不等待相应结果可以做其他的事,如果接收方不能立马返回IO结果,那么就一直等待返回结果后再响应发送端

异步非阻塞

  • 发送方向接收方发起请求后,发送方不用等待,接收方不能立马得到结果的话也不等待,当IO操作完成后,将完成状态和结果通知接收方,接收方再响应发送方.