nginx 子请求
来源:互联网 发布:易语言mp3播放器源码 编辑:程序博客网 时间:2024/05/18 20:09
主要分析子请求的以下问题
1,子请求怎么创建
2,子请求怎么触发
3,子请求的配置
4,子请求的变量
5,子请求可否设置缓存
6,子请求的location会不会打印log
1,子请求怎么创建
ngx_http_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)
第一个参数为创建子请求的主请求,
第二个参数为子请求的uri,
第三个参数为子请求的参数,
第四个参数为主请求创建的子请求指针
第五个参数为ngx_http_post_subrequest_t类型的结构体指针,主要目的是子请求在结束时做回调,通常用于向主请求传递一些信息
第六个参数为创建子请求时创建的flg,flag的值有 NGX_HTTP_SUBREQUEST_IN_MEMORY NGX_HTTP_SUBREQUEST_WAITED
ngx_http_subrequest函数的流程为:
如果r->main->count的值大于65535 - 1000,则返回错误,也就是子请求只能最多有65535 - 1000
对子请求分配空间,对于子请求里面的变量赋值
其中sr->connection=r->connection,也就是说子请求和父请求公用一个connection,
对子请求创建上下文,sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
对子请求的headers_out分配空间ngx_list_init(&sr->headers_out.headers, r->pool, 20,sizeof(ngx_table_elt_t)
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
sr->main_conf = cscf->ctx->main_conf;
sr->srv_conf = cscf->ctx->srv_conf;
sr->loc_conf = cscf->ctx->loc_conf;
sr->pool = r->pool;
sr->headers_in = r->headers_in;
sr->request_body = r->request_body;
sr->stream = r->stream;
sr->method = NGX_HTTP_GET;(子请求只能是GET)
sr->http_version = r->http_version;
sr->request_line = r->request_line;
sr->unparsed_uri = r->unparsed_uri;
sr->method_name = ngx_http_core_get_method;
sr->http_protocol = r->http_protocol;
sr->variables = r->variables;(子请求可以使用父请求的所有变量)
sr->log_handler = r->log_handler;
请求的这些配置都跟主请求一致
sr->uri = *uri;(函数传递下来的参数)这个uri什么使用用?还没有发现?
if (args) {
sr->args = *args;(函数传递下来的参数)
}
sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;这个标志表示把获取到的数据放到内存里面
sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;这个标志还没有弄清楚?
sr->main = r->main;
sr->parent = r;
sr->post_subrequest = ps;
sr->read_event_handler = ngx_http_request_empty_handler;
sr->write_event_handler = ngx_http_handler;
sr->internal = 1;子请求的internal设置的是1
pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
if (pr == NULL) {
return NGX_ERROR;
}
pr->request = sr;
pr->out = NULL;
pr->next = NULL;
if (r->postponed) {
for (p = r->postponed; p->next; p = p->next) { /* void */ }
p->next = pr;
} else {
r->postponed = pr; 把当前子请求加入到主请求的postponed中
}
把子请求sr挂在主请求r->postponed下面,是一个链表结构
接着调用ngx_http_post_request,调用形式为ngx_http_post_request(sr, NULL)
传递的第一个参数为sr,新创建的子请求,第二个参数为空
该函数主要作用就是把当前创建的子请求加入到子请求的主请求的posted_requests
2,子请求怎么运行
可以看到子请求创建后主要被加入到主请求的posted_requests和postponed里面,接下来就查看这两个成员什么时候使用?
对于posted_requests成员,可以看到在ngx_http_run_posted_requests里面调用
ngx_http_run_posted_requests函数的执行流程为:
遍历 r->main->posted_requests然后执行每个子请求的write_event_handler,也就是ngx_http_handler
ngx_http_handler的调用形式为ngx_http_handler(ngx_http_request_t *r)
执行流程为:
子请求的r->internal为1
设置r->phase_handler = cmcf->phase_engine.server_rewrite_index;也就是让子请求从server_rewrite阶段开始执行
对于子请求做以下设置:
r->valid_location = 1; 什么作用?
r->gzip_tested = 0;
r->gzip_ok = 0;
r->gzip_vary = 0;
然后r->write_event_handler设置为ngx_http_core_run_phases;
调用 ngx_http_core_run_phases(r);
ngx_http_core_run_phases函数就是从r->phase_handler位置往后执行,也就是server_rewrite
需要说明的是:子请求会跳过NGX_HTTP_ACCESS_PHASE的处理函数,相关分析可以参考 ngx phasehanler文章
postponed 主要是在postpone_filter_module以及finalize_request时使用(暂时不分析)
ngx_http_run_posted_requests函数主要是在
ngx_http_process_request(ngx_http_request_t *r)
ngx_http_request_handler(ngx_event_t *ev)这两个函数调用,这个两个函数可以保证所有的子请求都会被执行到
3,子请求的配置
子请求在创建的时候会指向父请求的配置的指针,在server_rewrite之后会进行修改,如何修改,这篇暂不讨论
4,子请求的变量
子请求的变量和父请求的变量执行的是同一个地方,在解析配置阶段父请求的变量已经进行解析拼凑变量,并且把变量的值存储在对应的index里面,子请求会取到和父请求一样的变量值。
5,子请求可否设置缓存
子请求可以在其匹配location里面设置缓存
6,子请求的location会不会打印log
子请求默认情况下不会打印log,log_subrequest设置为on,会打印log。
- nginx 子请求
- nginx子请求并发处理
- nginx配置子域名跳转到后端请求
- nginx子请求数量过多导致的内存泄漏
- nginx 处理请求
- Nginx 如何处理请求
- nginx请求超长解决方案
- nginx请求体读取
- nginx http请求PHASE
- Nginx与Gzip请求
- Nginx HTTP请求流程
- 向nginx发送请求
- nginx的请求处理
- nginx+tomcat重复请求
- 统计nginx某个请求
- nginx请求转发
- Nginx HTTP请求流程
- Nginx转发请求
- 杭州异地身份证办理条件以及材料
- x264参数介绍
- Windows+spyder中no module named 'tensorflow'解决方法
- java笔记--关于int和byte[]的转换
- 微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
- nginx 子请求
- Win32 串口编程(一)
- Radan 余料功能的使用
- MapReduce生成HFile入库到HBase及源码分析
- Linux系统
- Win32 串口编程(二)
- 极其简单的 使用IDEA 中 实现springboot 热部署 (spring boot devtools版)
- WebApi 接口参数不再困惑:传参详解
- Highway Networks