设为首页收藏本站

安徽论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 10828|回复: 0

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

[复制链接]

90

主题

863

回帖

1573

积分

金牌会员

Rank: 6Rank: 6

积分
1573
发表于 2022-3-26 11:00:42 | 显示全部楼层 |阅读模式
网站内容均来自网络,本站只提供信息平台,如有侵权请联系删除,谢谢!
首先说明一下应用方式,有两个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。
  1.     r->main = r;
  2.     r->count = 1;
复制代码
2、jtxy模块里处理请求时,调用了ngx_http_subrequest来创建一个子请求,在ngx_http_subrequest里计数被加1。
此时,count为2
  1.     r->main->count++;
复制代码
3、从一个模块出去(这里就是jtxy模块),会调用ngx_http_finalize_request,在ngx_http_finalize_request里会计数减一。
此时,count为1。
  1.     if (r->content_handler) {
  2.         r->write_event_handler = ngx_http_request_empty_handler;
  3.         ngx_http_finalize_request(r, r->content_handler(r));
  4.         return NGX_OK;
  5.     }
复制代码
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次的。
  1.     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。
  1. ngx_int_tngx_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
  1. static void
  2. ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
  3. {
  4.     ngx_connection_t  *c;

  5.     r = r->main;
  6.     c = r->connection;

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

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

  12.     r->count--;
复制代码
6、然后呢,因为子请求使用了upstream,因为这个原因count加了一次1,那么当upstream结束,就要减一次1。
此时count为1。

7、子请求完成后,父请求的回调方法接着处理,接下来就回到了主请求模块jtxy里,这里在处理结束后就会调用ngx_http_finalize_request来结束掉这个请求了,此时count为1,请求就会被释放掉了。
  1. void
  2. ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
  3. {
  4.     ngx_log_t                 *log;
  5.     ngx_pool_t                *pool;
  6.     struct linger              linger;
  7.     ngx_http_cleanup_t        *cln;
  8.     ngx_http_log_ctx_t        *ctx;
  9.     ngx_http_core_loc_conf_t  *clcf;

  10.     log = r->connection->log;

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

  12.     if (r->pool == NULL) {
  13.         ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed");
  14.         return;
  15.     }
复制代码
总结
到此这篇关于nginx中一个请求的count计数跟踪的文章就介绍到这了,更多相关nginx请求的count计数跟踪内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
                                                        
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
免责声明
1. 本论坛所提供的信息均来自网络,本网站只提供平台服务,所有账号发表的言论与本网站无关。
2. 其他单位或个人在使用、转载或引用本文时,必须事先获得该帖子作者和本人的同意。
3. 本帖部分内容转载自其他媒体,但并不代表本人赞同其观点和对其真实性负责。
4. 如有侵权,请立即联系,本网站将及时删除相关内容。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表