ITPub博客

首页 > > > 初探nginx-ngx_chain_t(100%)

初探nginx-ngx_chain_t(100%)

作者:longmanma 时间:2019-12-13 17:40:23 0 删除 编辑

ngx_chain_t(100%)

nginx的filter模块在处理从别的filter模块或者是handler模块传递过来的数据(实际上就是需要发送给客户端的http response)。这个传递过来的数据是以一个链表的形式(ngx_chain_t)。而且数据可能被分多次传递过来。也就是多次调用filter的处理函数,以不同的ngx_chain_t。

该结构被定义在src/core/ngx_buf.h|c。下面我们来看一下ngx_chain_t的定义。

typedef struct ngx_chain_s ngx_chain_t;

struct ngx_chain_s {

ngx_buf_t *buf;

ngx_chain_t *next;

};

就2个字段,next指向这个链表的下个节点。buf指向实际的数据。所以在这个链表上追加节点也是非常容易,只要把末尾元素的next指针指向新的节点,把新节点的next赋值为NULL即可。

ngx_chain_t*ngx_alloc_chain_link(ngx_pool_t*pool);

该函数创建一个ngx_chain_t的对象,并返回指向对象的指针,失败返回NULL。

#define ngx_free_chain(pool, cl) \

cl->next = pool->chain; \

pool->chain = cl

该宏释放一个ngx_chain_t类型的对象。如果要释放整个chain,则迭代此链表,对每个节点使用此宏即可。

注意: 对ngx_chaint_t类型的释放,并不是真的释放了内存,而仅仅是把这个对象挂在了这个pool对象的一个叫做chain的字段对应的chain上,以供下次从这个pool上分配ngx_chain_t类型对象的时候,快速的从这个pool->chain上取下链首元素就返回了,当然,如果这个链是空的,才会真的在这个pool上使用ngx_palloc函数进行分配。

ngx_buf_t(99%)

这个ngx_buf_t就是这个ngx_chain_t链表的每个节点的实际数据。该结构实际上是一种抽象的数据结构,它代表某种具体的数据。这个数据可能是指向内存中的某个缓冲区,也可能指向一个文件的某一部分,也可能是一些纯元数据(元数据的作用在于指示这个链表的读取者对读取的数据进行不同的处理)。

该数据结构位于src/core/ngx_buf.h|c文件中。我们来看一下它的定义。

struct ngx_buf_s {

u_char *pos;

u_char *last;

off_t file_pos;

off_t file_last;

u_char *start; /* start of buffer */

u_char *end; /* end of buffer */

ngx_buf_tag_t tag;

ngx_file_t *file;

ngx_buf_t *shadow;

/* the buf's content could be changed */

unsigned temporary:1;

/*

* the buf's content is in a memory cache or in a read only memory

* and must not be changed

*/

unsigned memory:1;

/* the buf's content is mmap()ed and must not be changed */

unsigned mmap:1;

unsigned recycled:1;

unsigned in_file:1;

unsigned flush:1;

unsigned sync:1;

unsigned last_buf:1;

unsigned last_in_chain:1;

unsigned last_shadow:1;

unsigned temp_file:1;

/* STUB */ int num;

};

pos:当buf所指向的数据在内存里的时候,pos指向的是这段数据开始的位置。

last:当buf所指向的数据在内存里的时候,last指向的是这段数据结束的位置。

file_pos:当buf所指向的数据是在文件里的时候,file_pos指向的是这段数据的开始位置在文件中的偏移量。

file_last:当buf所指向的数据是在文件里的时候,file_last指向的是这段数据的结束位置在文件中的偏移量。

start:当buf所指向的数据在内存里的时候,这一整块内存包含的内容可能被包含在多个buf中(比如在某段数据中间插入了其他的数据,这一块数据就需要被拆分开)。那么这些buf中的start和end都指向这一块内存的开始地址和结束地址。而pos和last指向本buf所实际包含的数据的开始和结尾。

end:解释参见start。

tag:实际上是一个void*类型的指针,使用者可以关联任意的对象上去,只要对使用者有意义。

file:当buf所包含的内容在文件中时,file字段指向对应的文件对象。

shadow:当这个buf完整copy了另外一个buf的所有字段的时候,那么这两个buf指向的实际上是同一块内存,或者是同一个文件的同一部分,此时这两个buf的shadow字段都是指向对方的。那么对于这样的两个buf,在释放的时候,就需要使用者特别小心,具体是由哪里释放,要提前考虑好,如果造成资源的多次释放,可能会造成程序崩溃!

temporary:为1时表示该buf所包含的内容是在一个用户创建的内存块中,并且可以被在filter处理的过程中进行变更,而不会造成问题。

memory:为1时表示该buf所包含的内容是在内存中,但是这些内容却不能被进行处理的filter进行变更。

mmap:为1时表示该buf所包含的内容是在内存中, 是通过mmap使用内存映射从文件中映射到内存中的,这些内容却不能被进行处理的filter进行变更。

recycled:可以回收的。也就是这个buf是可以被释放的。这个字段通常是配合shadow字段一起使用的,对于使用ngx_create_temp_buf 函数创建的buf,并且是另外一个buf的shadow,那么可以使用这个字段来标示这个buf是可以被释放的。

in_file:为1时表示该buf所包含的内容是在文件中。

flush:遇到有flush字段被设置为1的的buf的chain,则该chain的数据即便不是最后结束的数据(last_buf被设置,标志所有要输出的内容都完了),也会进行输出,不会受postpone_output配置的限制,但是会受到发送速率等其他条件的限制。

sync:

last_buf:数据被以多个chain传递给了过滤器,此字段为1表明这是最后一个buf。

last_in_chain:在当前的chain里面,此buf是最后一个。特别要注意的是last_in_chain的buf不一定是last_buf,但是last_buf的buf一定是last_in_chain的。这是因为数据会被以多个chain传递给某个filter模块。

last_shadow:在创建一个buf的shadow的时候,通常将新创建的一个buf的last_shadow置为1。

temp_file:由于受到内存使用的限制,有时候一些buf的内容需要被写到磁盘上的临时文件中去,那么这时,就设置此标志 。

对于此对象的创建,可以直接在某个ngx_pool_t上分配,然后根据需要,给对应的字段赋值。也可以使用定义好的2个宏:

#define ngx_alloc_buf(pool) ngx_palloc(pool, sizeof(ngx_buf_t))

#define ngx_calloc_buf(pool) ngx_pcalloc(pool, sizeof(ngx_buf_t))

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2730/viewspace-3153718/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: Hadoop集群安装-2
请登录后发表评论 登录
全部评论

注册时间:2019-12-18

  • 博文量
    492
  • 访问量
    11997