nginx 的请求处理、请求的处理流程

nginx的请求处理

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。

nginx使用一个多进程模型来对外提供服务,其中一个master进程,多个worker进程。master进程负责管理nginx本身和其他worker进程。

所有实际上的业务处理逻辑都在worker进程。worker进程中有一个函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个nginx服务被停止。

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

  1. 操作系统提供的机制(例如epoll, kqueue等)产生相关的事件。
  2. 接收和处理这些事件,如是接受到数据,则产生更高层的request对象。
  3. 处理request的header和body。
  4. 产生响应,并发送回客户端。
  5. 完成request的处理。
  6. 重新初始化定时器及其他事件。

请求的处理流程

为了让大家更好的了解nginx中请求处理过程,我们以HTTP Request为例,来做一下详细地说明。

从nginx的内部来看,一个HTTP Request的处理过程涉及到以下几个阶段。

  1. 初始化HTTP Request(读取来自客户端的数据,生成HTTP Request对象,该对象含有该请求所有的信息)。
  2. 处理请求头。
  3. 处理请求体。
  4. 如果有的话,调用与此请求(URL或者Location)关联的handler。
  5. 依次调用各phase handler进行处理。

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

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

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

一个phase handler通常执行以下几项任务:

  1. 获取location配置。
  2. 产生适当的响应。
  3. 发送response header。
  4. 发送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依次尝试:

  1. 如果一个location里面有配置 random_index on,那么随机选择一个文件,发送给客户端。
  2. 如果一个location里面有配置 index指令,那么发送index指令指明的文件,给客户端。
  3. 如果一个location里面有配置 autoindex on,那么就发送请求地址对应的服务端路径下的文件列表给客户端。
  4. 如果这个request对应的location上有设置gzip_static on,那么就查找是否有对应的.gz文件存在,有的话,就发送这个给客户端(客户端支持gzip的情况下)。
  5. 请求的URI如果对应一个静态文件,static module就发送静态文件的内容到客户端。

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

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

  1. server-side includes。
  2. XSLT filtering。
  3. 图像缩放之类的。
  4. gzip压缩。

在所有的filter中,有几个filter模块需要关注一下。按照调用的顺序依次说明如下:

write:写输出到客户端,实际上是写到连接对应的socket上。
postpone:这个filter是负责subrequest的,也就是子请求的。
copy:将一些需要复制的buf(文件或者内存)重新复制一份然后交给剩余的body filter处理。

转自:http://tengine.taobao.org/book/chapter_02.html#id13 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448216.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何控制油门更准确?

学员问:平时练车还不错,可是一换车就容易加大油门,有什么方法能很好的控制油呢?? 如何控制油门更准确?和调的座位有关系吗?? 答:油门跟刹车被视为汽车控制的灵魂。汽车发…

使用线程——创建线程

CreateThread函数创建一个进程的新的线程。创建线程必须指定新线程要执行的代码的起始地址。通常,起始地址是程序代码中定义的函数的名称(有关更多信息,请参阅ThreadProc)。此函数采用单个参数并返回DWORD值。一个进程可以让多个线…

location

location (地址): 是浏览器 window 上的一个对象,不仅能处理当前页面的网络地址,还可以实现页面间的跳转 页面的跳转: 为什么使用它? 使我们也可以通过脚本语言,也能实现 a 链接,同样的效果&…

linux :Docker 方式 安装 zookeeper、阿里服务器上 Docker 运行 zookeeper

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 1. 查找官方镜像,并下载镜像: # 搜索镜像: docker search zookeeper# 拉取镜像:docker …

使用线程池功能

此示例创建自定义线程池,创建工作项和线程池计时器,并将它们与清理组关联。该池由一个持久性线程组成。它演示了以下线程池函数的使用: CloseThreadpool CloseThreadpoolCleanupGroupCloseThreadpoolCleanupGroupMembersCloseThreadpoolWait…

制动刹车片六个养护要点

刹车片属于消耗品,在使用中会逐渐磨损,当磨损到极限位置时,必须更换,否则将降低制动的效果,甚至造成安全事故。 制动刹车片关乎生命安全,必须谨慎对待。 大多数轿车采用前盘后鼓式制动器结构,一…

Learn day4 函数参数\变量\闭包\递归

1.函数描述 # ### 函数 """ (1)函数的定义:功能 (包裹一部分代码 实现某一个功能 达成某一个目的) (2)函数特点:可以反复调用,提高代码的复用性,提高开发效率,便于维护管理 """# (3) 函数的基本格式 """ # 函数的定义处 def fun…

Java 中去除字符串中空格的方法

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 1、方法分类 str.trim(); //去掉首尾空格str.replace(" ",""); //去除所有空格,包括首尾、中间str.re…

使用重定向的输入和输出创建子进程

本主题中的示例演示如何使用控制台进程中的CreateProcess函数创建子进程。它还演示了一种使用匿名管道重定向子进程的标准输入和输出句柄的技术。请注意,命名管道也可用于重定向进程I / O. 所述CreatePipe函数使用SECURITY_ATTRIBUTES结构来创建可继承句柄读写两个…

手动挡停车时挂档有技巧

徐小姐来电:我家的汽车要年检了,前几天,工作人员帮我把车子开进检测站去检测,开回来后停在原位上,然后把钥匙交给我。我拿钥匙一点火,车子就突然往前动了,根本没有时间反应,已经撞到…

LOJ 3156: 「NOI2019」回家路线

题目传送门&#xff1a;LOJ #3156。 题意简述&#xff1a; 有一张 \(n\) 个点 \(m\) 条边的有向图&#xff0c;边有两个权值 \(p_i\) 和 \(q_i\)&#xff08;\(p_i<q_i\)&#xff09;表示若 \(p_i\) 时刻在这条边的起点&#xff0c;则 \(q_i\) 时刻能到达这条边的终点。 你需…

线程池概述

线程池 一个线程池的工作线程代表应用程序的高效执行异步回调的集合。线程池主要用于减少应用程序线程的数量并提供工作线程的管理。应用程序可以对工作项进行排队&#xff0c;将工作与可等待的句柄相关联&#xff0c;根据计时器自动排队&#xff0c;并与I / O绑定。 线程池架…

WEB 请求处理二:Nginx 请求 反向代理

上一篇《WEB请求处理一&#xff1a;浏览器请求发起处理》&#xff0c;我们讲述了浏览器端请求发起过程&#xff0c;通过DNS域名解析服务器IP&#xff0c;并建立TCP连接&#xff0c;发送HTTP请求。本文将讲述请求到达反向代理服务器的一个处理过程&#xff0c;比如&#xff1a;在…

方向盘的正确驾驭方法

如果问您油门踏板和方向盘哪个与驾驶员最“亲密”&#xff0c;您会选择谁呢&#xff1f;恐怕还是方向盘吧。如果汽车行驶过程中您的双手同时离开了方向盘&#xff0c;那么事故的隐患也就随之而来。下面我们就为您全面介绍汽车方向盘的正确使用方法。专家介绍&#xff0c;握方向…

SQL server 2005中无法新建作业(Job)的问题

客户端是使用企业管理其&#xff08;Management Studio&#xff09;新建job&#xff0c;总是无法创建&#xff0c;查找了很多资料&#xff0c;有的说是需要sp2, 但有的又说不是... ... 没有时间去研究为什么&#xff0c;但确有一种方法解决&#xff1a;到服务器端去创建job&…

线程池API

线程池API 线程池应用程序编程接口&#xff08;API&#xff09;使用基于对象的设计。以下每个对象都由用户模式数据结构表示&#xff1a; 池对象是一组可用于执行工作的工作线程。每个进程可以根据需要创建具有不同特征的多个隔离池。每个进程都有一个默认池。清理组与一组回…

WEB 请求处理 一:浏览器 请求发起处理

最近&#xff0c;终于要把《WEB请求处理系列》提上日程了&#xff0c;一直答应小伙伴们给分享一套完整的WEB请求处理流程&#xff1a;从浏览器、Nginx、Servlet容器&#xff0c;最终到应用程序WEB请求的一个处理流程&#xff0c;前段时间由于其他工作事情的安排&#xff0c;一直…

离合器半联动探秘

离合器踏板作用是切断发动机和变速箱之间的动力&#xff0c;有利于起步、变速、和停车。那么如何更好的使用它呢&#xff1f; 离合器的五种状态示意图 离合器半联动的使用方法揭密如下&#xff1a; 离合器半联动的使用探密之一 将离合器抬到车开始动时你就别再抬了&#xff0c;…

Biztalk Server 2006安装配置

前段时间收到了来自beta.microsoft.com的BTS20006 Beta2的下载地址&#xff0c;这两天对它进行了一番安装配置。下面把一些经过和步骤和大家分享一下&#xff0c;手中有一些去年的Biztalk Server2004版本的培训资料&#xff0c;里面有11个Lab。需要的朋友请留下mail&#xff0c…

apache 官方 Dubbo 文档

只是分享、记录一下 dubbo 的文档地址&#xff1a;apache 官方 Dubbo 文档 其页面内容如下&#xff1a;&#xff08;我是用 chrome 直接右键翻译的&#xff0c;原文档是英文的&#xff09;