nginx http处理(postpone延迟处理过滤器)

24人阅读 评论(0) 收藏 举报
分类:

        ngx_http_postpone_filter_module 用于处理延时的http请求(主要是子请求配置的)。postpone过滤器发生的时间点在处理响应包体时,这也是这个模块名称的由来。延时处理过滤功能和子请求之间的联系在点击打开链接子请求的说明里。

        postpone的处理流程也比较简单:先配置top_body_filter处理函数指针,然后再通过配置的函数处理发生作用。

        第一步,先配置top_body_filter处理函数 这个函数会在处理响应包体时发生作用,body_filter并非只有一个函数,而是通过设置top_body_filter来形成一个链式的处理结构,不同的body_filter的区别在于函数挂载的先后次序,先挂载的先处理,后挂载的后处理。

        第二步,通过配置的top_body_filter函数对响应包体的内容进行处理,如果存在postpone待处理的请求,进行必要的设置及处理的工作,下面以代码的处理流程作为说明。

static ngx_int_t
ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
{

    ...
    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
                   "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in);
    /*connection中保存的数据不是当前的请求*/
    if (r != c->data) {

        if (in) {  /* 待处理的buffer链是有效的 会将当前的http请求增加到postpone链表中 并将in的链表拷贝到postpone中
                    */
            if (ngx_http_postpone_filter_add(r, in) != NGX_OK) {
                return NGX_ERROR;
            }   /*由于connection中保存的数据不是当前的请求 直接返回*/
            return NGX_OK;
        }

#if 0
        /* TODO: SSI may pass NULL */
        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                      "http postpone filter NULL inactive request");
#endif

        return NGX_OK;
    }

    if (r->postponed == NULL) {
       /*如果请求的postponed链表是空的 说明不需要进行postpone处理 直接交由后一个body_filter处理即可*/
        if (in || c->buffered) {
            return ngx_http_next_body_filter(r->main, in);
        }

        return NGX_OK;
    }

    if (in) {   /*把in拷贝到postpone中 并加入到postponed链表*/
        if (ngx_http_postpone_filter_add(r, in) != NGX_OK) {
            return NGX_ERROR;
        }
    }

    do {  /*正式处理postponed链表 */
        pr = r->postponed;

        if (pr->request) {
          /*postpone存在请求 先将postponed处理切换到当前的postpone下一个*/
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                           "http postpone filter wake \"%V?%V\"",
                           &pr->request->uri, &pr->request->args);

            r->postponed = pr->next;

            c->data = pr->request;
            /*将当前的postpone中保存的请求提交到主请求的posted_request链表中 这里处理完一个就直接返回了*/
            return ngx_http_post_request(pr->request, NULL);
        }

        if (pr->out == NULL) {   /*发现postpone响应buffer链是空的 报错*/
            ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                          "http postpone filter NULL output");

        } else {   /*postpone响应buffer链是有效的 将其交予下一个body_filter进行处理*/
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                           "http postpone filter output \"%V?%V\"",
                           &r->uri, &r->args);

            if (ngx_http_next_body_filter(r->main, pr->out) == NGX_ERROR) {
                return NGX_ERROR;
            }
        }
        /*postponed遍历至下一个*/
        r->postponed = pr->next;

    } while (r->postponed);

    return NGX_OK;
}

   ngx_http_postponed_request_t 结构加入到http请求的postponed链表中

static ngx_int_t
ngx_http_postpone_filter_add(ngx_http_request_t *r, ngx_chain_t *in)
{
    ngx_http_postponed_request_t  *pr, **ppr;

    if (r->postponed) {  /*请求的postponed链表是存在的 遍历到最后一个*/
        for (pr = r->postponed; pr->next; pr = pr->next) { /* void */ }

        if (pr->request == NULL) { /*postpone中保存的请求是无效的 直接使用*/
            goto found;
        }

        ppr = &pr->next;

    } else {   /*请求的postponed链表是无效的 作为第一个即可*/
        ppr = &r->postponed;
    }
    /*为新的postpone分配空间*/
    pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
    if (pr == NULL) {
        return NGX_ERROR;
    }
    /*设置到postponed链表中*/
    *ppr = pr;
    /*必要的初始化*/
    pr->request = NULL;
    pr->out = NULL;
    pr->next = NULL;

found:
    /*拷贝in的buffer链内容到postpone响应buffer链中*/
    if (ngx_chain_add_copy(r->pool, &pr->out, in) == NGX_OK) {
        return NGX_OK;
    }

    return NGX_ERROR;
}

查看评论

商业数据分析与处理

-
  • 1970年01月01日 08:00

nginx处理http

ngx_http_read_client_request_body    HTTP包体的长度有可能非常大,如果试图一次性调用并读取完所有的包体,那么多半会阻塞Nginx进程。HTTP框架提供了一种...
  • evsqiezi
  • evsqiezi
  • 2017-01-22 15:32:23
  • 370

nginx处理http请求

上一篇文章分析了ngixn服务器如何接收客户端发来的http请求行、http请求头部。本文在这基础上分析nginx服务器收到http请求行、请求头部后,http框架是如何调度各个http模块共同完成这...
  • ApeLife
  • ApeLife
  • 2017-01-15 14:56:53
  • 1911

Nginx中http请求处理过程

  • 2012年11月24日 20:49
  • 361KB
  • 下载

NGINX中HTTP请求的11个处理阶段

Nginx的模块化设计使得每一个HTTP模块可以仅专注于完成一个独立的、简单的功能,而一个请求的完整处理过程可以由无数个HTTP模块共同合作完成。这种设计有非常好的简单性、可测试性、可扩展性,然而,当...
  • lijinqi1987
  • lijinqi1987
  • 2016-11-03 14:48:25
  • 2481

nginx处理http请求流程

http://blog.itpub.net/15480802/viewspace-1393025/ 监听套接字ngx_listenting_t->fd由获取accept_mutex的worker...
  • zhaoliang831214
  • zhaoliang831214
  • 2016-05-21 14:30:15
  • 1269

【Nginx】HTTP请求的11个处理阶段

Nginx将一个HTTP请求分成多个阶段,以模块为单位进行处理。这样做的好处是使处理过程更加灵活、降低耦合度。HTTP框架将处理分成了11个阶段,各个阶段以流水线的方式处理请求。这11个HTTP阶段如...
  • jy02326166
  • jy02326166
  • 2014-06-14 21:41:31
  • 5017

Nginx中http请求的处理过程

1.补充点: 如果不指定ngx_http_core_loc_conf_t ->handler,那么请求转发到默认的content phase中的handler(如ngx_http_ind...
  • eric_za
  • eric_za
  • 2014-12-25 17:22:55
  • 2959

nginx 如何处理一个HTTP请求

基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求。让我们从一个简单的配置(其中全部3个虚拟主机都在端口*:80上监听)开始: server { listen ...
  • xiancaione
  • xiancaione
  • 2015-06-04 11:10:21
  • 522

文章18 :Nginx中http请求的处理过程

虽然我不想承认,但这篇文章的确是一篇很垃圾的博文。之所以垃圾 是因为没有考虑到Nginx的事件驱动对于请求处理的影响。建议各位看官去阅读  《http://tengine.taobao.org/bo...
  • yankai0219
  • yankai0219
  • 2012-11-24 20:55:22
  • 17742
    个人资料
    持之以恒
    等级:
    访问量: 2111
    积分: 209
    排名: 34万+
    文章存档
    最新评论