nginx浅析

Nginx浅析html

目录nginx

一、简述... 1web

二、Nginx功能概述... 1算法

三、Nginx 架构... 2后端

四、Nginx 基础概念... 3缓存

五、Nginx 的模块化体系结构... 5服务器

六、Nginx工做原理... 6网络

一、反向代理与正向代理... 6数据结构

二、Nginx模块... 7多线程

三、Nginx请求处理... 9

参考文献:... 17

 

一、简述

Nginx 是一个高性能的HTTP和反向代理服务器,同时也是一个 IMAP/POP3/SMTP 代理服务器。Nginx 以事件驱动的方式编写,因此有很是好的性能,同时也是一个很是高效的反向代理、负载平衡。

二、Nginx功能概述

_HTTP基础功能:__

处理静态文件,索引文件以及自动索引;

反向代理加速(无缓存),简单的负载均衡和容错;

FastCGI,简单的负载均衡和容错;

模块化的结构。过滤器包括gzipping, byte ranges, chunked responses, 以及 SSI-filter 。在SSI过滤器中,到同一个 proxy 或者 FastCGI 的多个子请求并发处理;

SSL 和 TLS SNI 支持;

__其余HTTP功能:

基于IP 和名称的虚拟主机服务;

Memcached 的 GET 接口;

支持 keep-alive 和管道链接;

灵活简单的配置;

从新配置和在线升级而无须中断客户的工做进程;

可定制的访问日志,日志写入缓存,以及快捷的日志回卷;

4xx-5xx 错误代码重定向;

基于 PCRE 的 rewrite 重写模块;

基于客户端 IP 地址和 HTTP 基本认证的访问控制;

PUT, DELETE, 和 MKCOL 方法;

支持 FLV (Flash 视频);

带宽限制;

__IMAP/POP3 代理服务功能:

使用外部 HTTP 认证服务器重定向用户到 IMAP/POP3 后端;

使用外部 HTTP 认证服务器认证用户后链接重定向到内部的 SMTP 后端;

认证方法:

POP3: POP3 USER/PASS, APOP, AUTH LOGIN PLAIN CRAM-MD5;

IMAP: IMAP LOGIN;

SMTP: AUTH LOGIN PLAIN CRAM-MD5;

SSL 支持;

在 IMAP 和 POP3 模式下的 STARTTLS 和 STLS 支持;

__支持的操做系统:

FreeBSD 3.x, 4.x, 5.x, 6.x i386; FreeBSD 5.x, 6.x amd64;

Linux 2.2, 2.4, 2.6 i386; Linux 2.6 amd64;

Solaris 8 i386; Solaris 9 i386 and sun4u; Solaris 10 i386;

MacOS X (10.4) PPC;

__结构与扩展:

一个主进程和多个工做进程。工做进程是单线程的,且不须要特殊受权便可运行;

kqueue (FreeBSD 4.1+), epoll (Linux 2.6+), rt signals (Linux 2.2.19+), /dev/poll (Solaris 7 11/99+), select, 以及 poll 支持;

kqueue支持的不一样功能包括 EV_CLEAR, EV_DISABLE (临时禁止事件), NOTE_LOWAT, EV_EOF, 有效数据的数目,错误代码;

sendfile (FreeBSD 3.1+), sendfile (Linux 2.2+), sendfile64 (Linux 2.4.21+), 和 sendfilev (Solaris 8 7/01+) 支持;

输入过滤 (FreeBSD 4.1+) 以及 TCP_DEFER_ACCEPT (Linux 2.4+) 支持;

10,000 非活动的 HTTP keep-alive 链接仅须要 2.5M 内存。

最小化的数据拷贝操做;

 

本文主要关注nginx做为http服务器的基础功能

三、Nginx 架构

Nginx 是以多进程的方式来工做的,进程包含一个 master 进程和多个 worker 进程。master 进程主要用来管理 worker 进程,包含:接收来自外界的信号,向各 worker 进程发送信号,监控 worker 进程的运行状态,当 worker 进程退出后(异常状况下),会自动从新启动新的 worker 进程。而基本的网络事件,则是放在 worker 进程中来处理了。多个 worker 进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个 worker 进程中处理,一个 worker 进程,不可能处理其它进程的请求。worker 进程的个数是能够设置的,通常咱们会设置与机器cpu核数一致,这里面的缘由与 Nginx 的进程模型以及事件处理模型是分不开的。Nginx 的进程模型,能够由下图来表示:

 

从上文中咱们能够看到,master 来管理 worker 进程,因此咱们只须要与 master 进程通讯就好了。master 进程会接收来自外界发来的信号,再根据信号作不一样的事情。因此咱们要控制 Nginx,只须要向 master 进程发送信号就好了。

四、Nginx 基础概念

       Connection:在 Nginx 中 connection 就是对 tcp 链接的封装,其中包括链接的 socket,读事件,写事件。利用 Nginx 封装的 connection,咱们能够很方便的使用 Nginx 来处理与链接相关的事情,好比,创建链接,发送与接受数据等。结合一个 tcp 链接的生命周期,咱们看看 Nginx 是如何处理一个链接的。首先,Nginx 在启动时,会解析配置文件,获得须要监听的端口与 ip 地址,而后在 Nginx 的 master 进程里面,先初始化好这个监控的 socket(建立 socket,设置 addrreuse 等选项,绑定到指定的 ip 地址端口,再 listen),而后再 fork 出多个子进程出来,而后子进程会竞争 accept 新的链接。此时,客户端就能够向 Nginx 发起链接了。当客户端与服务端经过三次握手创建好一个链接后,Nginx 的某一个子进程会 accept 成功,获得这个创建好的链接的 socket,而后建立 Nginx 对链接的封装,即 ngx_connection_t 结构体。接着,设置读写事件处理函数并添加读写事件来与客户端进行数据的交换。最后,Nginx 或客户端来主动关掉链接,到此,一个链接就寿终正寝了。

       Request:在 Nginx 中咱们指的是 http 请求,具体到 Nginx 中的数据结构是ngx_http_request_t。ngx_http_request_t 是对一个 http 请求的封装。 Nginx 经过 ngx_http_request_t 来保存解析请求与输出响应相关的数据。下面是 Nginx 处理一个完整的请求的处理流程图;

 

Keepalive:在 Nginx 中,对于 http1.0 与 http1.1 也是支持长链接的。什么是长链接呢?咱们知道,http 请求是基于 TCP 协议之上的,那么,当客户端在发起请求前,须要先与服务端创建 TCP 链接,而每一次的 TCP 链接是须要三次握手来肯定的,若是客户端与服务端之间网络差一点,这三次交互消费的时间会比较多,并且三次交互也会带来网络流量。固然,当链接断开后,也会有四次的交互,固然对用户体验来讲就不重要了。而 http 请求是请求应答式的,若是咱们能知道每一个请求头与响应体的长度,那么咱们是能够在一个链接上面执行多个请求的,这就是所谓的长链接,但前提条件是咱们先得肯定请求头与响应体的长度。

Pipe:pipeline 其实就是流水线做业,它能够看做为 keepalive 的一种升华,由于 pipeline 也是基于长链接的,目的就是利用一个链接作屡次请求。若是客户端要提交多个请求,对于keepalive来讲,那么第二个请求,必需要等到第一个请求的响应接收彻底后,才能发起,这和 TCP 的中止等待协议是同样的,获得两个响应的时间至少为2*RTT。而对 pipeline 来讲,客户端没必要等到第一个请求处理完后,就能够立刻发起第二个请求。获得两个响应的时间可能可以达到1*RTT。Nginx 是直接支持 pipeline 的,可是,Nginx 对 pipeline 中的多个请求的处理却不是并行的,依然是一个请求接一个请求的处理,只是在处理第一个请求的时候,客户端就能够发起第二个请求。这样,Nginx 利用 pipeline 减小了处理完一个请求后,等待第二个请求的请求头数据的时间。其实 Nginx 的作法很简单,前面说到,Nginx 在读取数据时,会将读取的数据放到一个 buffer 里面,因此,若是 Nginx 在处理完前一个请求后,若是发现 buffer 里面还有数据,就认为剩下的数据是下一个请求的开始,而后就接下来处理下一个请求,不然就设置 keepalive。

lingering_close:lingering_close,字面意思就是延迟关闭,也就是说,当 Nginx 要关闭链接时,并不是当即关闭链接,而是先关闭 tcp 链接的写,再等待一段时间后再关掉链接的读。

五、Nginx 的模块化体系结构

       Nginx 的内部结构是由核心部分和一系列的功能模块所组成。核心部分(Nginx core)实现了底层的通信协议,为其余模块和 Nginx 进程构建了基本的运行时环境,而且构建了其余各模块的协做基础。除此以外,或者说大部分与协议相关的,或者应用相关的功能都是在这些模块中所实现的。

Nginx 的模块根据其功能基本上能够分为如下几种类型:

event module: 搭建了独立于操做系统的事件处理机制的框架,及提供了各具体事件的处理。包括 ngx_events_module, ngx_event_core_module和ngx_epoll_module 等。Nginx 具体使用何种事件处理模块,这依赖于具体的操做系统和编译选项。

phase handler: 此类型的模块也被直接称为 handler 模块。主要负责处理客户端请求并产生待响应内容,好比 ngx_http_static_module 模块,负责客户端的静态页面请求处理并将对应的磁盘文件准备为响应内容输出。

output filter: 也称为 filter 模块,主要是负责对输出的内容进行处理,能够对输出进行修改。例如,能够实现对输出的全部 html 页面增长预约义的 footbar 一类的工做,或者对输出的图片的 URL 进行替换之类的工做。

upstream: upstream 模块实现反向代理的功能,将真正的请求转发到后端服务器上,并从后端服务器上读取响应,发回客户端。upstream 模块是一种特殊的 handler,只不过响应内容不是真正由本身产生的,而是从后端服务器上读取的。

load-balancer: 负载均衡模块,实现特定的算法,在众多的后端服务器中,选择一个服务器出来做为某个请求的转发服务器。

六、Nginx工做原理

一、反向代理与正向代理

       反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的链接请求,而后将请求转发给内部网络上的服务器,并将从服务器上获得的结果返回给internet上请求链接的客户端,此时代理服务器对外就表现为一个服务器。

 

正向代理(Forward Proxy)一般都被简称为代理,就是在用户没法正常访问外部资源,比方说受到GFW的影响没法访问twitter的时候,咱们能够经过代理的方式,让用户绕过防火墙,从而链接到目标网络或者服务。

 

二、Nginx模块

     一、模块划分

nginx有五大优势:模块化、事件驱动、异步、非阻塞、多进程单线程。由内核和模块组成的,其中内核完成的工做比较简单,仅仅经过查找配置文件将客户端请求映射到一个location block,而后又将这个location block中所配置的每一个指令将会启动不一样的模块去完成相应的工做。

Nginx的模块从结构上分为核心模块、基础模块和第三方模块:

核心模块:HTTP模块、EVENT模块和MAIL模块

基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块,

第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块。

 

Nginx的模块从功能上分为以下四类:

Core(核心模块):构建nginx基础服务、管理其余模块。

Handlers(处理器模块):此类模块直接处理请求,并进行输出内容和修改headers信息等操做。

Filters (过滤器模块):此类模块主要对其余处理器模块输出的内容进行修改操做,最后由Nginx输出。

Proxies (代理类模块):此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务好比FastCGI等进行交互,实现服务代理和负载均衡等功能。

 

Nginx的核心模块主要负责创建nginx服务模型、管理网络层和应用层协议、以及启动针对特定应用的一系列候选模块。其余模块负责分配给web服务器的实际工做:

(1) 当Nginx发送文件或者转发请求到其余服务器,由Handlers(处理模块)或Proxies(代理类模块)提供服务;

(2) 当须要Nginx把输出压缩或者在服务端加一些东西,由Filters(过滤模块)提供服务。

 

二、模块处理

当服务器启动,每一个handlers(处理模块)都有机会映射到配置文件中定义的特定位置(location);若是有多个handlers(处理模块)映射到特定位置时,只有一个会“赢”(说明配置文件有冲突项,应该避免发生)。

处理模块以三种形式返回:

 

OK

ERROR

或者放弃处理这个请求而让默认处理模块来处理(主要是用来处理一些静态文件,事实上若是是位置正确而真实的静态文件,默认的处理模块会抢先处理)。

若是handlers(处理模块)把请求反向代理到后端的服务器,就变成另一类的模块:load-balancers(负载均衡模块)。负载均衡模块的配置中有一组后端服务器,当一个HTTP请求过来时,它决定哪台服务器应当得到这个请求。

Nginx的负载均衡模块采用两种方法:

 

轮转法,它处理请求就像纸牌游戏同样从头至尾分发;

 

IP哈希法,在众多请求的状况下,它确保来自同一个IP的请求会分发到相同的后端服务器。

 

若是handlers(处理模块)没有产生错误,filters(过滤模块)将被调用。多个filters(过滤模块)能映射到每一个位置,因此(好比)每一个请求均可以被压缩成块。它们的执行顺序在编译时决定。

filters(过滤模块)是经典的“接力链表(CHAIN OF RESPONSIBILITY)”模型:一个filters(过滤模块)被调用,完成其工做,而后调用下一个filters(过滤模块),直到最后一个filters(过滤模块)。

 

过滤模块链的特别之处在于:

 

每一个filters(过滤模块)不会等上一个filters(过滤模块)所有完成;

 

它能把前一个过滤模块的输出做为其处理内容;有点像Unix中的流水线;

 

过滤模块能以buffer(缓冲区)为单位进行操做,这些buffer通常都是一页(4K)大小,固然你也能够在nginx.conf文件中进行配置。这意味着,好比,模块能够压缩来自后端服务器的响应,而后像流同样的到达客户端,直到整个响应发送完成。总之,过滤模块链以流水线的方式高效率地向客户端发送响应信息。

总结下上面的内容,一个典型的HTTP处理周期是这样的:

客户端发送HTTP请求 –>

Nginx基于配置文件中的位置选择一个合适的处理模块 ->

(若是有)负载均衡模块选择一台后端服务器 –>

处理模块进行处理并把输出缓冲放到第一个过滤模块上 –>

第一个过滤模块处理后输出给第二个过滤模块 –>

而后第二个过滤模块又到第三个 –>

依此类推 –> 最后把响应发给客户端。

 

下图展现了Nginx模块处理流程:

 

Nginx自己作的工做实际不多,当它接到一个HTTP请求时,它仅仅是经过查找配置文件将这次请求映射到一个location block,而此location中所配置的各个指令则会启动不一样的模块去完成工做,所以模块能够看作Nginx真正的劳动工做者。一般一个location中的指令会涉及一个handler模块和多个filter模块(固然,多个location能够复用同一个模块)。handler模块负责处理请求,完成响应内容的生成,而filter模块对响应内容进行处理

三、Nginx请求处理

Nginx在启动时会以daemon形式在后台运行,采用多进程+异步非阻塞IO事件模型来处理各类链接请求。多进程模型包括一个master进程,多个worker进程,通常worker进程个数是根据服务器CPU核数来决定的。master进程负责管理Nginx自己和其余worker进程。以下图:

 

从上图中能够很明显地看到,4个worker进程的父进程都是master进程,代表worker进程都是从父进程fork出来的,而且父进程的ppid为1,表示其为daemon进程。

 

须要说明的是,在nginx多进程中,每一个worker都是平等的,所以每一个进程处理外部请求的机会权重都是一致的。

 

Master进程的做用是:

读取并验证配置文件nginx.conf;管理worker进程;

Worker进程的做用是:

每个Worker进程都维护一个线程(避免线程切换),处理链接和请求;注意Worker进程的个数由配置文件决定,通常和CPU个数相关(有利于进程切换),配置几个就有几个Worker进程。

 

Nginx如何作到热部署?

所谓热部署,就是配置文件nginx.conf修改后,不须要stop Nginx,不须要中断请求,就能让配置文件生效!(nginx -s reload 从新加载/nginx -t检查配置/nginx -s stop)

经过上文咱们已经知道worker进程负责处理具体的请求,那么若是想达到热部署的效果,能够想象:

方案一:

修改配置文件nginx.conf后,主进程master负责推送给woker进程更新配置信息,woker进程收到信息后,更新进程内部的线程信息。

方案二:

修改配置文件nginx.conf后,从新生成新的worker进程,固然会以新的配置进行处理请求,并且新的请求必须都交给新的worker进程,至于老的worker进程,等把那些之前的请求处理完毕后,kill掉便可。

Nginx采用的就是方案二来达到热部署的!

 

Nginx挂了怎么办?

Nginx既然做为入口网关,很重要,若是出现单点问题,显然是不可接受的。

答案是:Keepalived+Nginx实现高可用。

Keepalived是一个高可用解决方案,主要是用来防止服务器单点发生故障,能够经过和Nginx配合来实现Web服务的高可用。(其实,Keepalived不只仅能够和Nginx配合,还能够和不少其余服务配合)

Keepalived+Nginx实现高可用的思路:

第一:请求不要直接打到Nginx上,应该先经过Keepalived(这就是所谓虚拟IP,VIP)

第二:Keepalived应该能监控Nginx的生命状态(提供一个用户自定义的脚本,按期检查Nginx进程状态,进行权重变化,,从而实现Nginx故障切换)

 

Nginx架构及工做流程图:

 

Nginx真正处理请求业务的是Worker之下的线程。worker进程中有一个ngx_worker_process_cycle()函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个Nginx服务被中止。

 

worker 进程中,ngx_worker_process_cycle()函数就是这个无限循环的处理函数。在这个函数中,一个请求的简单处理流程以下:

操做系统提供的机制(例如 epoll, kqueue 等)产生相关的事件。

接收和处理这些事件,如是接收到数据,则产生更高层的 request 对象。

处理 request 的 header 和 body。

产生响应,并发送回客户端。

完成 request 的处理。

从新初始化定时器及其余事件。

3.1 多进程处理模型

下面来介绍一个请求进来,多进程模型的处理方式:

首先,master进程一开始就会根据咱们的配置,来创建须要listen的网络socket fd,而后fork出多个worker进程。

其次,根据进程的特性,新创建的worker进程,也会和master进程同样,具备相同的设置。所以,其也会去监听相同ip端口的套接字socket fd。

而后,这个时候有多个worker进程都在监听一样设置的socket fd,意味着当有一个请求进来的时候,全部的worker都会感知到。这样就会产生所谓的“惊群现象”。为了保证只会有一个进程成功注册到listenfd的读事件,nginx中实现了一个“accept_mutex”相似互斥锁,只有获取到这个锁的进程,才能够去注册读事件。其余进程所有accept 失败。

最后,监听成功的worker进程,读取请求,解析处理,响应数据返回给客户端,断开链接,结束。所以,一个request请求,只须要worker进程就能够完成。

进程模型的处理方式带来的一些好处就是:进程之间是独立的,也就是一个worker进程出现异常退出,其余worker进程是不会受到影响的;此外,独立进程也会避免一些不须要的锁操做,这样子会提升处理效率,而且开发调试也更容易。

如前文所述,多进程模型+异步非阻塞模型才是胜出的方案。单纯的多进程模型会致使链接并发数量的下降,而采用异步非阻塞IO模型很好的解决了这个问题;而且还所以避免的多线程的上下文切换致使的性能损失。

worker进程会竞争监听客户端的链接请求:这种方式可能会带来一个问题,就是可能全部的请求都被一个worker进程给竞争获取了,致使其余进程都比较空闲,而某一个进程会处于忙碌的状态,这种状态可能还会致使没法及时响应链接而丢弃discard掉本有能力处理的请求。这种不公平的现象,是须要避免的,尤为是在高可靠web服务器环境下。

针对这种现象,Nginx采用了一个是否打开accept_mutex选项的值,ngx_accept_disabled标识控制一个worker进程是否须要去竞争获取accept_mutex选项,进而获取accept事件。

ngx_accept_disabled值:nginx单进程的全部链接总数的八分之一,减去剩下的空闲链接数量,获得的这个ngx_accept_disabled。

当ngx_accept_disabled大于0时,不会去尝试获取accept_mutex锁,而且将ngx_accept_disabled减1,因而,每次执行到此处时,都会去减1,直到小于0。不去获取accept_mutex锁,就是等于让出获取链接的机会,很显然能够看出,当空闲链接越少时,ngx_accept_disable越大,因而让出的机会就越多,这样其它进程获取锁的机会也就越大。不去accept,本身的链接就控制下来了,其它进程的链接池就会获得利用,这样,nginx就控制了多进程间链接的平衡了。

3.2 一个简单的HTTP请求

从 Nginx 的内部来看,一个 HTTP Request 的处理过程涉及到如下几个阶段:

初始化 HTTP Request(读取来自客户端的数据,生成 HTTP Request 对象,该对象含有该请求全部的信息)。

处理请求头。

处理请求体。

若是有的话,调用与此请求(URL 或者 Location)关联的 handler。

依次调用各 phase handler 进行处理。

在创建链接过程当中,对于nginx监听到的每一个客户端链接,都会将它的读事件的handler设置为ngx_http_init_request函数,这个函数就是请求处理的入口。在处理请求时,主要就是要解析http请求,好比:uri,请求行等,而后再根据请求生成响应。下面看一下nginx处理的具体过程:

 

在这里,咱们须要了解一下 phase handler 这个概念。phase 字面的意思,就是阶段。因此 phase handlers 也就好理解了,就是包含若干个处理阶段的一些 handler。

在每个阶段,包含有若干个 handler,再处理到某个阶段的时候,依次调用该阶段的 handler 对 HTTP Request 进行处理。

一般状况下,一个 phase handler 对这个 request 进行处理,并产生一些输出。一般 phase handler 是与定义在配置文件中的某个 location 相关联的。

一个 phase handler 一般执行如下几项任务:

获取 location 配置。

产生适当的响应。

发送 response header。

发送 response body。

当 Nginx 读取到一个 HTTP Request 的 header 的时候,Nginx 首先查找与这个请求关联的虚拟主机的配置。若是找到了这个虚拟主机的配置,那么一般状况下,这个 HTTP Request 将会通过如下几个阶段的处理(phase handlers):

NGX_HTTP_POST_READ_PHASE: 读取请求内容阶段

NGX_HTTP_SERVER_REWRITE_PHASE: Server 请求地址重写阶段

NGX_HTTP_FIND_CONFIG_PHASE: 配置查找阶段

NGX_HTTP_REWRITE_PHASE: Location请求地址重写阶段

NGX_HTTP_POST_REWRITE_PHASE: 请求地址重写提交阶段

NGX_HTTP_PREACCESS_PHASE: 访问权限检查准备阶段

NGX_HTTP_ACCESS_PHASE: 访问权限检查阶段

NGX_HTTP_POST_ACCESS_PHASE: 访问权限检查提交阶段

NGX_HTTP_TRY_FILES_PHASE: 配置项 try_files 处理阶段

NGX_HTTP_CONTENT_PHASE: 内容产生阶段

NGX_HTTP_LOG_PHASE: 日志模块处理阶段

在内容产生阶段,为了给一个 request 产生正确的响应,Nginx 必须把这个 request 交给一个合适的 content handler 去处理。若是这个 request 对应的 location 在配置文件中被明确指定了一个 content handler,那么Nginx 就能够经过对 location 的匹配,直接找到这个对应的 handler,并把这个 request 交给这个 content handler 去处理。这样的配置指令包括像,perl,flv,proxy_pass,mp4等。

若是一个 request 对应的 location 并无直接有配置的 content handler,那么 Nginx 依次尝试:

若是一个 location 里面有配置 random_index on,那么随机选择一个文件,发送给客户端。

若是一个 location 里面有配置 index 指令,那么发送 index 指令指明的文件,给客户端。

若是一个 location 里面有配置 autoindex on,那么就发送请求地址对应的服务端路径下的文件列表给客户端。

若是这个 request 对应的 location 上有设置 gzip_static on,那么就查找是否有对应的.gz文件存在,有的话,就发送这个给客户端(客户端支持 gzip 的状况下)。

请求的 URI 若是对应一个静态文件,static module 就发送静态文件的内容到客户端。

内容产生阶段完成之后,生成的输出会被传递到 filter 模块去进行处理。filter 模块也是与 location 相关的。全部的 filter 模块都被组织成一条链。输出会依次穿越全部的 filter,直到有一个 filter 模块的返回值代表已经处理完成。

这里列举几个常见的 filter 模块,例如:

server-side includes。

XSLT filtering。

图像缩放之类的。

gzip 压缩。

在全部的 filter 中,有几个 filter 模块须要关注一下。按照调用的顺序依次说明以下:

copy: 将一些须要复制的 buf(文件或者内存)从新复制一份而后交给剩余的 body filter 处理。

postpone: 这个 filter 是负责 subrequest 的,也就是子请求的。

write: 写输出到客户端,其实是写到链接对应的 socket 上。

3.3 请求完整处理过程

根据以上请求步骤所述,请求完整的处理过程以下图所示:

 

参考文献:

https://www.jianshu.com/p/6215e5d24553

http://www.javashuo.com/article/p-svivqglt-ho.html

https://www.w3cschool.cn/nginx/hwa71pe6.html

http://www.nginx.cn/doc/index.html

相关文章
相关标签/搜索