nginx中一个请求的count计数跟踪浅析

首先说明一下应用方式,有两个nginx的模块,一个名为jtxy,另一个名为jtcmd。一个http请求来了,会进入jtxy的模块处理,jtxy会创建出一个子请求发送给jtcmd,jtcmd里处理呢又会创建出一个upstream流到我们的上游非http服务A来处理,A处理完成后得到结果,会把结果返回给jtcmd的子请求,jtcmd的子请求把结果返回给jtxy。就是这样一个流程,我们来跟踪一下一个请的count计数。

1、请求到来,创建一个请求,ngx_http_alloc_request里count被初始化为1

此时,count为1。

    r->main = r;
    r->count = 1;

2、jtxy模块里处理请求时,调用了ngx_http_subrequest来创建一个子请求,在ngx_http_subrequest里计数被加1。

此时,count为2

    r->main->count++;

3、从一个模块出去(这里就是jtxy模块),会调用ngx_http_finalize_request,在ngx_http_finalize_request里会计数减一。

此时,count为1。

    if (r->content_handler) {
        r->write_event_handler = ngx_http_request_empty_handler;
        ngx_http_finalize_request(r, r->content_handler(r));
        return NGX_OK;
    }

4、然后进入了我们的子请求jtcmd模块,,在这个模块里,如果发现自己是个子请求((r!=r->main)),那么就应该把主请求计数加一。这里标红强调这点是因为如果不加1,那么主请求计数就会有问题,一会儿我们继续跟踪count的减1就会发现这个问题。

这里是jtxy发起的一个jtcmd子请求这里的r和r->main并不相同的,r是jtcmd,r->main就是jtxy。

此时,count为2。

同时因为我们子请求jtcmd模块里使用了upstream,那么count是还需要在加1,但是我们使用时是ngx_http_read_client_request_body(r, ngx_http_upstream_init),ngx_http_read_client_request_body里就已经加1了,所以,我们这里就不必自己来做这个加1了。

此时count为3。

大家可以看看《深入理解nginx》的5.1.5节的内容。对upstream流需要加1有讲解。

所以呢,这里的count是加了2次的。

    r->upstream->resolved->sockaddr =  (struct sockaddr*)&backendSockAddr;
    r->upstream->resolved->socklen =  sizeof(struct sockaddr_in);
    r->upstream->resolved->naddrs = 1;

    r->upstream->create_request = jtcmd_upstream_create_request;
    r->upstream->process_header = jtcmd_upstream_process_header;
    r->upstream->finalize_request = jtcmd_upstream_finalize_request;
    r->upstream->abort_request = jtcmd_upstream_abort_request;

    r->upstream->input_filter_init = ngx_http_jtcmd_filter_init;
    r->upstream->input_filter = ngx_http_jtcmd_filter;
    r->upstream->input_filter_ctx = jtcmdctx;

    //r->subrequest_in_memory = 1;

    if(r!=r->main)
    {
        r->main->count++;
    }

    ngx_int_t rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
    if (rc == NGX_ERROR || rc > NGX_OK) {
        return rc;
    }

这里的r是子请求,r->main是主请求。同时还注意到,子请求的count始终是0。

ngx_int_t
ngx_http_read_client_request_body(ngx_http_request_t *r,
    ngx_http_client_body_handler_pt post_handler)
{
    size_t                     preread;
    ssize_t                    size;
    ngx_int_t                  rc;
    ngx_buf_t                 *b;
    ngx_chain_t                out;
    ngx_http_request_body_t   *rb;
    ngx_http_core_loc_conf_t  *clcf;

    r->main->count++;

5、同第3一样,请求的处理完后会调用ngx_http_finalize_request把计数减一,但是这里不同的是我们这里是一个子请求,他这里有一步r = r->main;所以实际减时就减到了主请求上去了,这个也是我们在4里红字说明的要加1的原因了。

此时,count为2

static void
ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
{
    ngx_connection_t  *c;

    r = r->main;
    c = r->connection;

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                   "http request count:%d blk:%d", r->count, r->blocked);

    if (r->count == 0) {
        ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero");
    }

    r->count--;

6、然后呢,因为子请求使用了upstream,因为这个原因count加了一次1,那么当upstream结束,就要减一次1。

此时count为1。

7、子请求完成后,父请求的回调方法接着处理,接下来就回到了主请求模块jtxy里,这里在处理结束后就会调用ngx_http_finalize_request来结束掉这个请求了,此时count为1,请求就会被释放掉了。

void
ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
{
    ngx_log_t                 *log;
    ngx_pool_t                *pool;
    struct linger              linger;
    ngx_http_cleanup_t        *cln;
    ngx_http_log_ctx_t        *ctx;
    ngx_http_core_loc_conf_t  *clcf;

    log = r->connection->log;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http close request");

    if (r->pool == NULL) {
        ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed");
        return;
    }

总结

到此这篇关于nginx中一个请求的count计数跟踪的文章就介绍到这了,更多相关nginx请求的count计数跟踪内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • nginx中一个请求的count计数跟踪浅析

    首先说明一下应用方式,有两个nginx的模块,一个名为jtxy,另一个名为jtcmd.一个http请求来了,会进入jtxy的模块处理,jtxy会创建出一个子请求发送给jtcmd,jtcmd里处理呢又会创建出一个upstream流到我们的上游非http服务A来处理,A处理完成后得到结果,会把结果返回给jtcmd的子请求,jtcmd的子请求把结果返回给jtxy.就是这样一个流程,我们来跟踪一下一个请的count计数. 1.请求到来,创建一个请求,ngx_http_alloc_request里coun

  • Nginx中Location配置超详细讲解

    目录 一.语法 二.匹配顺序 三.root 与 alias 的区别 四.server 和 location 中的 root 总结 一.语法 Location 是 Nginx 中一个非常核心的配置,关于Location,举个简单的配置例子: server { listen 80; server_name 10.0.7.115; location / { root /data/app/; index index.html; } } 当访问 http://10.0.7.115:80 的时候,返回的是

  • 详解Nginx的核心配置模块中对于请求体的接受流程

    本篇文章主要会介绍nginx中请求的接收流程,包括请求头的解析和请求体的读取流程. 首先介绍一下rfc2616中定义的http请求基本格式: Request = Request-Line *(( general-header | request-header | entity-header ) CRLF) CRLF [ message-body ] </span> 第一行是请求行(request line),用来说明请求方法,要访问的资源以及所使用的HTTP版本: Request-Line  

  • Nginx中404页面的配置及AJAX请求返回404页面的方法

    404页面基础配置 404错误是WWW网站访问容易出现的错误.最常见的出错提示:404 NOT FOUND.404错误页的设置对网站SEO有很大的影响,而设置不当,比如直接转跳主页等,会被搜索引擎降权拔毛.404页面的目的应该是告诉用户:你所请求的页面是不存在的,同时引导用户浏览网站其他页面而不是关掉窗口离去.搜索引擎通过HTTP状态码来识别网页的状态.当搜索引擎获得了一个错误链接时,网站应该返回404状态码,告诉搜索引擎放弃对该链接的索引.而如果返回200或302状态码,搜索引擎就会为该链接建

  • nginx日志中添加请求的response日志(推荐)

    由于此功能在nginx内置的功能中没有,需要安装第三方模块ngx_lua,由于此模块需要Lua语言,所以需要安装相应的Lua语言包 1. 下载安装LuaJIT # cd /usr/local/src # wget http://luajit.org/download/LuaJIT-2.0.2.tar.gz # tar -xzvf LuaJIT-2.0.2.tar.gz # cd LuaJIT-2.0.2 # make 出现如下内容表示编译成功 OK Successfully built LuaJ

  • 浅谈Nginx 中的两种限流方式

    系统设计时一般会预估负载,当系统暴露在公网中时,恶意攻击或正常突发流量等都可能导致系统被压垮,而限流就是保护措施之一.限流即控制流量,本文将记录 Nginx 的二种限流设置. 生活中的 "限流"? 限流并非新鲜事,在生活中亦无处不在,下面例举一二: 博物馆:限制每天参观总人数以保护文物 高铁安检:有若干安检口,旅客依次排队,工作人员根据安检快慢决定是否放人进去.遇到节假日,可以增加安检口来提高处理能力(横向拓展),同时增加排队等待区长度(缓存待处理任务). 办理银行业务:所有人先领号,

  • 解读nginx中limit配置参数

    本文主要解析一下ngx_http_core_module.ngx_http_limit_conn_module以及ngx_http_limit_req_module中的limit相关配置参数. limit_rate 名称 默认配置 作用域 官方说明 中文解读 模块 limit_rate limit_rate 0; http, server, location, if in location Limits the rate of response transmission to a client.

  • 原生JavaScrpit中异步请求Ajax实现方法

    在前端页面开发的过程中,经常使用到Ajax请求,异步提交表单数据,或者异步刷新页面. 一般来说,使用Jquery中的$.ajax,$.post,$.getJSON,非常方便,但是有的时候,我们只因为需要ajax功能而引入Jquery比较不划算. 所以接下来便用原生JavaScrpit实现一个简单的Ajax请求,并说明ajax请求中的跨域访问问题,以及多个ajax请求的数据同步问题. JavaScript实现Ajax异步请求 简单的ajax请求实现 Ajax请求的原理是创建一个XMLHttpReq

  • Nginx中虚拟主机与指定访问路径的设置方法讲解

    添加多个虚拟主机 最近在ubuntu上捣腾nginx,安装成功了,就只有rewrite没有试验,因为服务器上有多个网站,还不敢在服务器上尝试,慢慢来.网上查了一些文章,下了一篇留下来做试验. nginx上虚拟主机的配置其实跟apache上的基本上类似. 需要注意的几点是: 第一.关于.htaccess配置,也就是为静态配置,在nginx上一般你要写在虚拟主机的配置文本中,但是我也有看到用包含文件解决这个问题的,即在虚拟主机配置脚本上include .htaccess文件,不过没有没有试过. 第二

  • 在Nginx中拦截特定用户代理的教程

    现代互联网滋生了大量各种各样的恶意机器人和网络爬虫,比如像恶意软件机器人.垃圾邮件程序或内容刮刀,这些恶意工具一直偷偷摸摸地扫描你的网站,干些诸如检测潜在网站漏洞.收获电子邮件地址,或者只是从你的网站偷取内容.大多数机器人能够通过它们的"用户代理"签名字符串来识别. 作为第一道防线,你可以尝试通过将这些机器人的用户代理字符串添加入robots.txt文件来阻止这些恶意软件机器人访问你的网站.但是,很不幸的是,该操作只针对那些"行为良好"的机器人,这些机器人被设计遵循

随机推荐