0

0

nginx的请求如何处理?

(*-*)浩

(*-*)浩

发布时间:2019-11-28 14:57:43

|

3444人浏览过

|

来源于php中文网

原创

nginx的请求如何处理?

今天我们讲 request,在 Nginx 中我们指的是 http 请求,具体到 Nginx 中的数据结构是ngx_http_request_t。ngx_http_request_t 是对一个 http 请求的封装。 我们知道,一个 http 请求,包含请求行、请求头、请求体、响应行、响应头、响应体。

http 请求是典型的请求-响应类型的的网络协议,而 http 是文本协议,所以我们在分析请求行与请求头,以及输出响应行与响应头,往往是一行一行的进行处理。       ( 推荐学习:nginx使用 )

如果我们自己来写一个 http 服务器,通常在一个连接建立好后,客户端会发送请求过来。然后我们读取一行数据,分析出请求行中包含的 method、uri、http_version 信息。

然后再一行一行处理请求头,并根据请求 method 与请求头的信息来决定是否有请求体以及请求体的长度,然后再去读取请求体。

得到请求后,我们处理请求产生需要输出的数据,然后再生成响应行,响应头以及响应体。

在将响应发送给客户端之后,一个完整的请求就处理完了。当然这是最简单的 webserver 的处理方式,其实 Nginx 也是这样做的,只是有一些小小的区别,比如,当请求头读取完成后,就开始进行请求的处理了。Nginx 通过 ngx_http_request_t 来保存解析请求与输出响应相关的数据。

那接下来,简要讲讲 Nginx 是如何处理一个完整的请求的。对于 Nginx 来说,一个请求是从ngx_http_init_request 开始的,在这个函数中,会设置读事件为 ngx_http_process_request_line,也就是说,接下来的网络事件,会由 ngx_http_process_request_line 来执行。

从ngx_http_process_request_line 的函数名,我们可以看到,这就是来处理请求行的,正好与之前讲的,处理请求的第一件事就是处理请求行是一致的。

通过 ngx_http_read_request_header 来读取请求数据。然后调用 ngx_http_parse_request_line 函数来解析请求行。Nginx 为提高效率,采用状态机来解析请求行,而且在进行 method 的比较时,没有直接使用字符串比较,而是将四个字符转换成一个整型,然后一次比较以减少 cpu 的指令数,这个前面有说过。

很多人可能很清楚一个请求行包含请求的方法,uri,版本,却不知道其实在请求行中,也是可以包含有 host 的。比如一个请求 GET http://www.taobao.com/uri HTTP/1.0 这样一个请求行也是合法的,而且 host 是 www.taobao.com,这个时候,Nginx 会忽略请求头中的 host 域,而以请求行中的这个为准来查找虚拟主机。

另外,对于对于 http0.9 版来说,是不支持请求头的,所以这里也是要特别的处理。所以,在后面解析请求头时,协议版本都是 1.0 或 1.1。整个请求行解析到的参数,会保存到 ngx_http_request_t 结构当中。

在解析完请求行后,Nginx 会设置读事件的 handler 为 ngx_http_process_request_headers,然后后续的请求就在 ngx_http_process_request_headers 中进行读取与解析。

ngx_http_process_request_headers 函数用来读取请求头,跟请求行一样,还是调用 ngx_http_read_request_header 来读取请求头,调用 ngx_http_parse_header_line 来解析一行请求头,解析到的请求头会保存到 ngx_http_request_t 的域 headers_in 中,headers_in 是一个链表结构,保存所有的请求头。

而 HTTP 中有些请求是需要特别处理的,这些请求头与请求处理函数存放在一个映射表里面,即 ngx_http_headers_in,在初始化时,会生成一个 hash 表,当每解析到一个请求头后,就会先在这个 hash 表中查找,如果有找到,则调用相应的处理函数来处理这个请求头。比如:Host 头的处理函数是 ngx_http_process_host。

当 Nginx 解析到两个回车换行符时,就表示请求头的结束,此时就会调用 ngx_http_process_request 来处理请求了。

ngx_http_process_request 会设置当前的连接的读写事件处理函数为 ngx_http_request_handler,然后再调用 ngx_http_handler 来真正开始处理一个完整的http请求。

阿里云AI平台
阿里云AI平台

阿里云AI平台

下载

这里可能比较奇怪,读写事件处理函数都是ngx_http_request_handler,其实在这个函数中,会根据当前事件是读事件还是写事件,分别调用 ngx_http_request_t 中的 read_event_handler 或者是 write_event_handler。

由于此时,我们的请求头已经读取完成了,之前有说过,Nginx 的做法是先不读取请求 body,所以这里面我们设置 read_event_handler 为 ngx_http_block_reading,即不读取数据了。

刚才说到,真正开始处理数据,是在 ngx_http_handler 这个函数里面,这个函数会设置 write_event_handler 为 ngx_http_core_run_phases,并执行 ngx_http_core_run_phases 函数。

ngx_http_core_run_phases 这个函数将执行多阶段请求处理,Nginx 将一个 http 请求的处理分为多个阶段,那么这个函数就是执行这些阶段来产生数据。

因为 ngx_http_core_run_phases 最后会产生数据,所以我们就很容易理解,为什么设置写事件的处理函数为 ngx_http_core_run_phases 了。

在这里,我简要说明了一下函数的调用逻辑,我们需要明白最终是调用 ngx_http_core_run_phases 来处理请求,产生的响应头会放在 ngx_http_request_t 的 headers_out 中,这一部分内容,我会放在请求处理流程里面去讲。Nginx 的各种阶段会对请求进行处理,最后会调用 filter 来过滤数据,对数据进行加工,如 truncked 传输、gzip 压缩等。

这里的 filter 包括 header filter 与 body filter,即对响应头或响应体进行处理。filter 是一个链表结构,分别有 header filter 与 body filter,先执行 header filter 中的所有 filter,然后再执行 body filter 中的所有 filter。

在 header filter 中的最后一个 filter,即 ngx_http_header_filter,这个 filter 将会遍历所有的响应头,最后需要输出的响应头在一个连续的内存,然后调用 ngx_http_write_filter 进行输出。

ngx_http_write_filter 是 body filter 中的最后一个,所以 Nginx 首先的 body 信息,在经过一系列的 body filter 之后,最后也会调用 ngx_http_write_filter 来进行输出(有图来说明)。

这里要注意的是,Nginx 会将整个请求头都放在一个 buffer 里面,这个 buffer 的大小通过配置项 client_header_buffer_size 来设置,如果用户的请求头太大,这个 buffer 装不下,那 Nginx 就会重新分配一个新的更大的 buffer 来装请求头,这个大 buffer 可以通过 large_client_header_buffers 来设置,这个 large_buffer 这一组 buffer,比如配置 48k,就是表示有四个 8k 大小的 buffer 可以用。

注意,为了保存请求行或请求头的完整性,一个完整的请求行或请求头,需要放在一个连续的内存里面,所以,一个完整的请求行或请求头,只会保存在一个 buffer 里面。

这样,如果请求行大于一个 buffer 的大小,就会返回 414 错误,如果一个请求头大小大于一个 buffer 大小,就会返回 400 错误。在了解了这些参数的值,以及 Nginx 实际的做法之后,在应用场景,我们就需要根据实际的需求来调整这些参数,来优化我们的程序了。

处理流程图:

nginx-42.png

以上这些,就是 Nginx 中一个 http 请求的生命周期了。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
nginx 重启
nginx 重启

nginx重启对于网站的运维来说是非常重要的,根据不同的需求,可以选择简单重启、平滑重启或定时重启等方式。本专题为大家提供nginx重启的相关的文章、下载、课程内容,供大家免费下载体验。

248

2023.07.27

nginx 配置详解
nginx 配置详解

Nginx的配置是指设置和调整Nginx服务器的行为和功能的过程。通过配置文件,可以定义虚拟主机、HTTP请求处理、反向代理、缓存和负载均衡等功能。Nginx的配置语法简洁而强大,允许管理员根据自己的需要进行灵活的调整。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

522

2023.08.04

nginx配置详解
nginx配置详解

NGINX与其他服务类似,因为它具有以特定格式编写的基于文本的配置文件。本专题为大家提供nginx配置相关的文章,大家可以免费学习。

610

2023.08.04

tomcat和nginx有哪些区别
tomcat和nginx有哪些区别

tomcat和nginx的区别:1、应用领域;2、性能;3、功能;4、配置;5、安全性;6、扩展性;7、部署复杂性;8、社区支持;9、成本;10、日志管理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

244

2024.02.23

nginx报404怎么解决
nginx报404怎么解决

当访问 nginx 网页服务器时遇到 404 错误,表明服务器无法找到请求资源,可以通过以下步骤解决:1. 检查文件是否存在且路径正确;2. 检查文件权限并更改为 644 或 755;3. 检查 nginx 配置,确保根目录设置正确、没有冲突配置等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

714

2024.07.09

Nginx报404错误解决方法
Nginx报404错误解决方法

解决方法:只需要加上这段配置:try_files $uri $uri/ /index.html;即可。想了解更多Nginx的相关内容,可以阅读本专题下面的文章。

3618

2024.08.07

nginx部署php项目教程汇总
nginx部署php项目教程汇总

本专题整合了nginx部署php项目教程汇总,阅读专题下面的文章了解更多详细内容。

56

2026.01.13

nginx配置文件详细教程
nginx配置文件详细教程

本专题整合了nginx配置文件相关教程详细汇总,阅读专题下面的文章了解更多详细内容。

72

2026.01.13

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

nginx浅谈
nginx浅谈

共15课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号