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

 更新时间:2022年01月04日 10:37:04   作者:wwyyxx26  
这篇文章主要给大家介绍了关于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计数跟踪内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Nginx 流量控制/限流的具体实现示例

    Nginx 流量控制/限流的具体实现示例

    限流是一种流量控制手段,用于限制单位时间内可以通过系统的请求数或连接数,本文主要介绍了Nginx流量控制/限流的具体实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • Nginx搭建高可用的实现

    Nginx搭建高可用的实现

    高可用HA是分布式系统架构设计中必须考虑的因素之一,本文主要介绍了Nginx搭建高可用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • nginx 访问限制与访问控制的实现

    nginx 访问限制与访问控制的实现

    访问控制要做的事情是控制客户端的资源访问权限,本文主要介绍了nginx 访问限制与访问控制的实现,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-02-02
  • Nginx中配置HTTP2协议的方法

    Nginx中配置HTTP2协议的方法

    HTTP2协议是HTTP的重大升级,提供多路复用、头部压缩和服务器推送等优点,正确配置HTTP2可以为用户提供更快、更流畅的访问体验,提升网站竞争力,本文就来介绍一下Nginx中配置HTTP2协议的方法,感兴趣的可以了解一下
    2024-10-10
  • nginx实现ip限流的具体示例

    nginx实现ip限流的具体示例

    限流的方式油很多种,本文主要介绍了nginx实现ip限流的具体示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07
  • nginx请求限制配置方法

    nginx请求限制配置方法

    这篇文章给大家介绍nginx请求限制配置方法,包括http协议的连接和请求,nginx配置语法,本文给大家介绍的非常详细,需要的朋友参考下吧
    2021-07-07
  • nginx内存池源码解析

    nginx内存池源码解析

    内存池是在真正使用内存之前,预先申请分配一定数量的、大小相等(一般情况下)的内存块留作备用,接下来通过本文给大家介绍nginx内存池源码,本文通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2021-11-11
  • Nginx中使用Lua脚本与图片的缩略图处理的实现

    Nginx中使用Lua脚本与图片的缩略图处理的实现

    本文主要介绍了Nginx中使用Lua脚本与图片的缩略图处理的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 浅析nginx刚刚发布的JavaScript能力nginScript

    浅析nginx刚刚发布的JavaScript能力nginScript

    Nginx [engine x]是全球最受欢迎,也是最优秀的web服务器、反向代理服务器。nginScript是JavaScript/ECMAscript的子集,nginScript不是通过V8引擎实现的。本文给大家介绍nginx刚刚发布的JavaScript能力nginScript,感兴趣的朋友跟着小编一起了解了解吧
    2015-09-09
  • Nginx反向代理后端服务的操作步骤

    Nginx反向代理后端服务的操作步骤

    反向代理是一种代理服务器,位于客户端与服务器之间,后端服务器处理请求后将响应发送回反向代理服务器,反向代理服务器再将响应返回给客户端,本文将详细介绍Nginx如何反向代理后端服务,涵盖其基本概念、配置方法、负载均衡、SSL/TLS支持等多个方面,需要的朋友可以参考下
    2024-06-06

最新评论