nginx中一個(gè)請(qǐng)求的count計(jì)數(shù)跟蹤淺析
首先說明一下應(yīng)用方式,有兩個(gè)nginx的模塊,一個(gè)名為jtxy,另一個(gè)名為jtcmd。一個(gè)http請(qǐng)求來了,會(huì)進(jìn)入jtxy的模塊處理,jtxy會(huì)創(chuàng)建出一個(gè)子請(qǐng)求發(fā)送給jtcmd,jtcmd里處理呢又會(huì)創(chuàng)建出一個(gè)upstream流到我們的上游非http服務(wù)A來處理,A處理完成后得到結(jié)果,會(huì)把結(jié)果返回給jtcmd的子請(qǐng)求,jtcmd的子請(qǐng)求把結(jié)果返回給jtxy。就是這樣一個(gè)流程,我們來跟蹤一下一個(gè)請(qǐng)的count計(jì)數(shù)。
1、請(qǐng)求到來,創(chuàng)建一個(gè)請(qǐng)求,ngx_http_alloc_request里count被初始化為1
此時(shí),count為1。
r->main = r;
r->count = 1;
2、jtxy模塊里處理請(qǐng)求時(shí),調(diào)用了ngx_http_subrequest來創(chuàng)建一個(gè)子請(qǐng)求,在ngx_http_subrequest里計(jì)數(shù)被加1。
此時(shí),count為2
r->main->count++;
3、從一個(gè)模塊出去(這里就是jtxy模塊),會(huì)調(diào)用ngx_http_finalize_request,在ngx_http_finalize_request里會(huì)計(jì)數(shù)減一。
此時(shí),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、然后進(jìn)入了我們的子請(qǐng)求jtcmd模塊,,在這個(gè)模塊里,如果發(fā)現(xiàn)自己是個(gè)子請(qǐng)求((r!=r->main)),那么就應(yīng)該把主請(qǐng)求計(jì)數(shù)加一。這里標(biāo)紅強(qiáng)調(diào)這點(diǎn)是因?yàn)槿绻患?,那么主請(qǐng)求計(jì)數(shù)就會(huì)有問題,一會(huì)兒我們繼續(xù)跟蹤count的減1就會(huì)發(fā)現(xiàn)這個(gè)問題。
這里是jtxy發(fā)起的一個(gè)jtcmd子請(qǐng)求這里的r和r->main并不相同的,r是jtcmd,r->main就是jtxy。
此時(shí),count為2。
同時(shí)因?yàn)槲覀冏诱?qǐng)求jtcmd模塊里使用了upstream,那么count是還需要在加1,但是我們使用時(shí)是ngx_http_read_client_request_body(r, ngx_http_upstream_init),ngx_http_read_client_request_body里就已經(jīng)加1了,所以,我們這里就不必自己來做這個(gè)加1了。
此時(shí)count為3。
大家可以看看《深入理解nginx》的5.1.5節(jié)的內(nèi)容。對(duì)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是子請(qǐng)求,r->main是主請(qǐng)求。同時(shí)還注意到,子請(qǐng)求的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一樣,請(qǐng)求的處理完后會(huì)調(diào)用ngx_http_finalize_request把計(jì)數(shù)減一,但是這里不同的是我們這里是一個(gè)子請(qǐng)求,他這里有一步r = r->main;所以實(shí)際減時(shí)就減到了主請(qǐng)求上去了,這個(gè)也是我們?cè)?里紅字說明的要加1的原因了。
此時(shí),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、然后呢,因?yàn)樽诱?qǐng)求使用了upstream,因?yàn)檫@個(gè)原因count加了一次1,那么當(dāng)upstream結(jié)束,就要減一次1。
此時(shí)count為1。

7、子請(qǐng)求完成后,父請(qǐng)求的回調(diào)方法接著處理,接下來就回到了主請(qǐng)求模塊jtxy里,這里在處理結(jié)束后就會(huì)調(diào)用ngx_http_finalize_request來結(jié)束掉這個(gè)請(qǐng)求了,此時(shí)count為1,請(qǐng)求就會(huì)被釋放掉了。
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;
}總結(jié)
到此這篇關(guān)于nginx中一個(gè)請(qǐng)求的count計(jì)數(shù)跟蹤的文章就介紹到這了,更多相關(guān)nginx請(qǐng)求的count計(jì)數(shù)跟蹤內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Logrotate如何實(shí)現(xiàn)每小時(shí)切割日志文件
這篇文章主要介紹了Logrotate如何實(shí)現(xiàn)每小時(shí)切割日志文件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
nginx服務(wù)器access日志中大量400 bad request錯(cuò)誤的解決方法
這篇文章主要介紹了nginx服務(wù)器access日志中大量400 bad request錯(cuò)誤的解決方法,本文結(jié)論是空主機(jī)頭導(dǎo)致的大量400錯(cuò)誤日志,關(guān)閉默認(rèn)主機(jī)的日志記錄就可以解決問題,需要的朋友可以參考下2015-01-01
nginx利用ctx實(shí)現(xiàn)數(shù)據(jù)共享、修改上下文功能
這篇文章主要給大家介紹了關(guān)于nginx利用ctx實(shí)現(xiàn)數(shù)據(jù)共享、修改上下文功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01
nginx使用sticky基于cookie的會(huì)話保持方式
這篇文章主要介紹了nginx使用sticky基于cookie的會(huì)話保持方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Nginx stub_status 監(jiān)控模塊的功能實(shí)現(xiàn)
本篇文章主要介紹了Nginx stub_status 監(jiān)控模塊的功能實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03

