关于subrequest
在 ngx_http_core_module 里面,我们可以看到一些subrequest的函数,根据evan miller 的文章,我们知道 subrequest是在主请求的基础上发起的子请求,subrequest返回的内容会被附加到自请求上面,他的实现方法就是调用 ngx_http_subrequest 函数,subrequest函数的圆形是
ngx_int_t
ngx_http_subrequest(ngx_http_request_t *r,
ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
在里面,在这个函数里,他会1)创建新的request变量,根据 主request的值去填充这个变量2)注册新的变量的write event handler
sr->read_event_handler = ngx_http_request_empty_handler;
sr->write_event_handler = ngx_http_handler;
3) 并且把subrequet 的request 注册到主request的 posted_requests 变量里
for (p = &r->main->posted_requests; *p; p = &(*p)->next) { /* void */ }
也就是说,一但调用了 ngx_http_subrequest 只后,subrequest已经已经注册到了nginx的事件循环中,和主循环并行进行处理,所以根据evan miller的文章里我们也可以看到,subrequest的串行处理是比较困难的。
关于 internal redirect
nginx的 internal redirect 有两种方式, 一个是调用 ngx_http_internal_redirect 命令, 一个是使用 X-Accel-Redirect 头,其中X-Accel-Redirect 头是交由upstream模块进行的, 在ngx_http_upstream_process_headers函数中,我们可以看到
if (u->headers_in.x_accel_redirect
&& !(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT))
{
.....
.....
ngx_http_internal_redirect(r, uri, &args);
return NGX_DONE;
}
也就是说,本质上,这两种方法都是通过 ngx_http_internal_redirect 的函数实现的,而ngx_http_internal_redirect 函数又做了些什么呢?
r->internal = 1;
ngx_http_handler(r);
return NGX_DONE;
可以看到,其实它只是简单的修改request结构体,并通过 ngx_http_handler 重新进行http处理流程而已。
关于internal redirect 和 subrequest,他们有类似的地方,都是在最后调用 ngx_http_handler 重新开始对request的处理,但是不同的地方我想主要是 subrequest会新建立一个request结构,原来的request处理并不会结束,而 internal redirect会结束当前的请求处理,使用嗯但前的request结构体来发起请求。
关于upstream
upstream是nginx里面非常重要的一种处理模式,nginx的很多模块都是使用他来完成的, upstream和普通的handler有很大的不同,比如nginx的location handler 和phase handler, 他们的处理模式非常类似apache的handler,就是获取后同步的进行处理,但是对于有些场合,比如proxy或者fastcgi, nginx进程需要和上游的服务(http,或者php-cgi)进行交互,并且将结果返回给客户端,在交互的过程中,由于后端服务的响应时间各异,如果后端服务的响应时间过长,nginx等待后端服务响应的过程一之同步阻塞在这里是不现实的,所以nginx采用了异步的方案,每当上游服务器有响应的时候才进行处理,并将处理结果返回给前端,这样nginx在处理上游请求的时候,可以同时注册多个io时间,使用epoll_wait(linux下默认) 也就是nginx的主事件循环进行处理,大大提高了nginx的并发能里,每个进程可以处理多个连接 ,不会因为一个上游连接阻塞整个nginx进程, 当然这也有依赖于你程序的实现方式。
关于upstream的使用方式, evan miller的文章里已经说的很清楚了,就是可以在location handler里(或者其它插入点中) 注册upstream的一些callback
u->conf = &plcf->upstream;
/* attach the callback functions */
u->create_request = ngx_http_proxy_create_request;
u->reinit_request = ngx_http_proxy_reinit_request;
u->process_header = ngx_http_proxy_process_status_line;
u->abort_request = ngx_http_proxy_abort_request;
u->finalize_request = ngx_http_proxy_finalize_request;
r->upstream = u;
并且最后在调用 ngx_http_read_client_request_body 中传入 ngx_http_upstream_init 作为callback function 参数初始化 upstream流程, 在 ngx_http_upsteam_init 里面,会调用 ngx_http_upstream_connect建立连接,并注册读写的event handler
/* event handler 最终会根据读/或者写的请求调用 write_event_handler和 read_event_handler ,也就是 ngx_http_upstream_send_request_handler和
ngx_http_upstream_process_header */
c->write->handler = ngx_http_upstream_handler;
c->read->handler = ngx_http_upstream_handler;
u->write_event_handler = ngx_http_upstream_send_request_handler;
u->read_event_handler = ngx_http_upstream_process_header;
这里需要注意的是,在处理上游请求的时候,由于是异步的事件,所以每次上游服务器在调用callback的时候并不一定返回的是全部数据,process_header 函数必须根据判断每次返回的数据包是否完成,如果没有处理完成则返回 NGX_AGAIN,来指示nginx需要重新进入process_header函数进行处理,并知道处理完成的时候返回NGX_OK 来指示nginx完成处理。 具体的例子可以参考 fastcgi 模块的ngx_http_fastcgi_process_header函数
另外, nginx可以针对上游服务的响应body进行处理, 通过注册 u->pipe->input_filter 这个回叫来实现,同样可以参考fastcgi模块,下面是例子
/* 这里注册对于响应体的处理 */
u->pipe->input_filter = ngx_http_fastcgi_input_filter;
u->pipe->input_ctx = r;
通常在处理的过程中需要自己创建状态机来处理请求的不同状态,对于一些请求相关的信息,可以自己创建结构体,通过
#define ngx_http_get_module_ctx(r, module) (r)->ctx[module.ctx_index]
#define ngx_http_set_ctx(r, c, module) r->ctx[module.ctx_index] = c;
这两个宏进行读取和存储。
相关推荐
### Nginx 代码研究知识点概览 #### 一、Nginx 概述与特点 **Nginx**(发音为 "engine X")是一款高性能的HTTP服务器、反向代理服务器以及IMAP/POP3/SMTP代理服务器。它以其高稳定性、丰富的功能集、示例配置文件...
在0.1版代码中,可以研究NGINX如何解析配置文件,理解指令解析、变量处理等过程,这对于定制和扩展NGINX配置有很大帮助。 通过对NGINX 0.1版源代码的分析,我们可以深入了解其基本架构和设计原则。尽管随着版本...
**Nginx Web服务器代码详解** Nginx是一款高性能、轻量级的Web服务器和反向代理服务器,因其高效的并发处理能力和低内存占用而受到广泛关注。它的设计目标是实现高并发、低延迟以及稳定性,因此在大型网站和互联网...
在 `src/core/ngx_event.h` 和 `src/event/ngx_event.c` 中,可以研究 Nginx 如何高效地处理网络事件。 **3. 多进程与多线程** Nginx 通常采用主进程+工作进程的模式,主进程负责管理工作进程和配置加载,工作进程...
通过研究Nginx 1.13.10的源代码,开发者不仅可以了解其工作原理,还能深入学习网络编程、并发处理、I/O模型等相关知识,对提升系统级编程技能大有裨益。同时,这也是定制Nginx功能、优化服务器性能的重要途径。
本资源提供的"nginx开源代码"为nginx的1.3.1版本,虽然不是最新版,但对于学习其核心架构和基本工作原理非常有帮助。 Nginx的源码分析主要涉及以下几个关键知识点: 1. **事件模型**:Nginx采用的是异步非阻塞的...
Nginx源代码分析最新版本深入解析 Nginx,作为高性能的HTTP和反向代理服务器,以及IMAP/POP3/SMTP服务器,自推出...同时,我们也欢迎更多的朋友参与到Nginx源代码的研究和讨论中来,共同推动互联网技术的发展与进步。
- 源代码中关于静态文件的缓存和优化策略值得研究,以便提高服务效率。 7. **错误处理与日志记录** - Nginx 有完善的错误处理机制,包括记录错误日志、返回错误页面等,这些在实际运维中非常关键。 - 源代码中的...
通过深入研究Nginx的源代码,开发者不仅可以学习到网络编程、并发处理、服务器架构等相关知识,还可以提升在高并发环境下的问题解决能力。对于想要优化Nginx或者基于Nginx进行二次开发的工程师来说,理解源代码是至...
深入研究Nginx的源代码,能帮助开发者理解如何构建高性能、低延迟的网络服务,并为自定义扩展提供基础。对于想要优化服务器性能或开发网络应用的人来说,理解Nginx的源代码无疑是一项重要的技能。
**NGINX源代码详解** ...通过深入学习和研究NGINX的源代码,开发者可以更好地理解和定制这款强大的Web服务器,以满足特定场景的需求。同时,NGINX的源代码也是学习网络编程、并发处理和高性能服务器设计的良好教材。
3. **编译Nginx**:进入Nginx源代码目录,执行`./configure`进行配置,然后用`make`和`sudo make install`进行编译和安装。 4. **编译PHP**:在PHP源代码目录下,同样执行`./configure --with-nginx`指定Nginx路径...
通过学习和研究"nginx web服务器最新代码",我们可以深入理解Nginx的工作机制,同时也能为旧版本的维护和升级提供参考。无论是初学者还是经验丰富的开发者,对Nginx的深入理解都是提高服务质量的关键。
通过研究这个早期版本,你可以深入了解Nginx是如何从最初的代码逐渐演变为如今广泛使用的Web服务器的。同时,这个过程也是对Linux系统编程的一次深入实践,有助于提升你在C/C++编程、网络编程和系统调用方面的技能。
深入研究 Nginx 1.3.14 的源代码,可以理解其模块化设计、事件驱动架构和高效并发处理能力。这对于开发基于 Nginx 的扩展功能或者优化现有部署都是必不可少的。同时,源代码中的注释也能帮助我们了解每个功能的实现...
对于想要深入了解Nginx工作原理、进行定制化开发或者参与Nginx社区的开发者来说,研究其源代码是必不可少的步骤。你可以通过阅读源码了解Nginx如何处理网络请求、如何实现高效的并发处理机制,以及它是如何与其他...
然后,结合《深入理解Nginx》深入研究Nginx的内部机制。同时,通过阅读和分析Nginx源码,可以更直观地看到这些概念如何在实际代码中实现。 总之,掌握Nginx源码不仅可以提升Web服务的运维技能,还能为开发者提供一...
收集的 nginx 源码 解析 ,非常全 architecture.png Emiller的Nginx模块开发指南.docx Nginx(en).pdf nginx@taobao.pdf nginx_internals.pdf nginx核心讲解(0.2).doc nginx核心讲解(0.4).doc ...Ningx代码研究.docx
**Nginx源代码分析与学习笔记** Nginx是一款高性能、轻量级的Web服务器/反向代理服务器,以其高效的并发处理能力、低内存占用和丰富的模块化设计而受到广泛应用。本文将深入探讨Nginx的源代码,并结合学习笔记,...
通过研究Nginx 1.5.7的源码,我们可以深入了解网络服务器的设计理念,学习如何构建高性能、高并发的应用。同时,对于希望改进或定制Nginx功能的开发者来说,源码阅读是必不可少的步骤。通过深入源码,我们可以发现更...