首页 > 系统相关 >Nginx底层基础数据结构

Nginx底层基础数据结构

时间:2024-03-18 12:32:59浏览次数:28  
标签:last ngx list 链表 Nginx 内存 数据结构 buf 底层

基础数据结构

ngx_int_t

32位操作系统4字节,64位操作系统8字节

解决跨平台以及,普通int类型在x86和x64操作系统上面是4字节,在类型转换时造成内存浪费(如在x64下面转换long类型)

typedef intptr_t        ngx_int_t;

#ifdef _WIN64
typedef __int64 intptr_t;
#else
typedef __int32 intptr_t;
#endif

ngx_str_t

在Nginx的领域中,ngx_str_t结构就是字符串。ngx_str_t的定义如下:

ngx_str_t只有两个成员,其中data指针指向字符串起始地址,len表示字符串的有效长度。注意,ngx_str_t的data成员指向的并不是普通的字符串,
因为这段字符串未必会以’\0’作为结尾,所以使用时必须根据长度len来使用data成员。

typedef struct {
    size_t      len;
    u_char     *data;
} ngx_str_t;

ngx_list_t

ngx_list_t描述整个链表,而ngx_list_part_t只描述链表的一个元素。这里要注意的是,ngx_list_t不是一个单纯的链表,为了便于理解,我们姑且称它为存储数组的链表,什么意思呢?抽象地说,就是每个链表元素ngx_list_part_t又是一个数组,拥有连续的内存,它既依赖于ngx_list_t里的size和nalloc来表示数组的容量,同时又依靠每个ngx_list_part_t成员中的nelts来表示数组当前已使用了多少容量。因此,ngx_list_t是一个链表容器,而链表中的元素又是一个数组。事实上,ngx_list_part_t数组中的元素才是用户想要存储的东西,ngx_list_t链表能够容纳的元素数量由ngx_list_part_t数组元素的个数与每个数组所能容纳的元素相乘得到。

这样设计有什么好处呢?
  • 链表中存储的元素是灵活的,它可以是任何一种数据结构。
  • 链表元素需要占用的内存由ngx_list_t管理,它已经通过数组分配好了。
  • 小块的内存使用链表访问效率是低下的,使用数组通过偏移量来直接访问内存则要高效得多。

image-20240122214654294

成员以及成员意义
  • ngx_list_part_s:链表的每一个节点
    • elts:指向数组的起始地址。
    • nelts:已经使用的容量
    • next:下一个节点
  • ngx_list_t:链表类
    • part:首节点,注意:首节点存储的是一个结构体,而不是指针
    • last:指向最后一个节点
    • size:节点的elts数组中存储的数据类型的最大大小
    • nalloc:链表的数组元素一旦分配后是不可更改的。nalloc表示每个ngx_list_part_t数组的容量,即最多可存储多少个数据。
    • pool:所属内存池,链表中管理内存分配的内存池对象。用户要存放的数据占用的内存都是由pool分配的
typedef struct ngx_list_part_s  ngx_list_part_t;

struct ngx_list_part_s { 
    void             *elts;
    ngx_uint_t        nelts;
    ngx_list_part_t  *next; 
};

typedef struct {
    ngx_list_part_t  *last; 
    ngx_list_part_t   part;
    size_t size;
    ngx_uint_t nalloc; 
    ngx_pool_t *pool; 
} ngx_list_t;

//创建链表
//n size分别对应ngx_list_t中的size和nalloc
ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size);

//链表初始化,在ngx_list_create会调用,无需自己调用
static ngx_inline ngx_int_t
ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size);

//添加元素
void *ngx_list_push(ngx_list_t *list);

ngx_table_elt_t

  • ngx_table_elt_t就是一个key/value对,ngx_str_t 类型的key、value成员分别存储的是名字、值字符串。

  • 显而易见,ngx_table_elt_t是为HTTP头部“量身订制”的,其中key存储头部名称(如Content-Length),value存储对应的值(如“1024”),

  • lowcase_key是为了忽略HTTP头部名称的大小写(例如,有些客户端发来的HTTP请求头部是content-length,Nginx希望它与大小写敏感的

  • Content-Length做相同处理,有了全小写的lowcase_key成员后就可以快速达成目的了),hash用于快速检索头部

typedef struct {
    ngx_uint_t        hash;//通过key value字符串计算出的hash值
    ngx_str_t         key;
    ngx_str_t         value;
    u_char           *lowcase_key;//存放的是本结构体中key的小写字母字符串
} ngx_table_elt_t;

ngx_buf_t

缓冲区ngx_buf_t是Nginx处理大数据的关键数据结构,它既应用于内存数据也应用于磁盘数据

ngx_buf_t是一种基本数据结构,本质上它提供的仅仅是一些指针成员和标志位。对于HTTP模块来说,需要注意HTTP框架、事件框架是如何设置和使用pos、last等指针以及如何处理这些标志位的,上述说明只是最常见的用法。(如果我们自定义一个ngx_buf_t结构体,不应当受限于上述用法,而应该根据业务需求自行定义。例如用一个ngx_buf_t缓冲区转发上下游TCP流时,pos会指向将要发送到下游的TCP流起始地址,而last会指向预备接收上游TCP流的缓冲区起始地址。)

成员以及成员意义
  • pos:指向从内存池里分配的内存。 pos为已扫描的内存端中,还未解析的内存的尾部,
  • last:last通常表示有效的内容到此为止
  • file_pos:将要处理的文件位置
  • file_last:截止的文件位置
  • start:指向ngx_buf_t的起始地址
  • end:与start成员对应,指向缓冲区内存的末尾
  • tag:表示当前缓冲区的类型,例如由哪个模块使用就指向这个模块ngx_module_t变量的地址
  • file:引用的文件 用于存储接收到所有包体后,把包体内容写入到file文件中,
  • shadow:当前缓冲区的影子缓冲区,该成员很少用到
  • temporary:临时内存标志位,为1时表示数据在内存中且这段内存可以修改
  • memory:标志位,为1时表示数据在内存中且这段内存不可以被修改
  • mmap:标志位,为1时表示这段内存是用mmap系统调用映射过来的,不可以被修改
  • recycled:标志位,为1时表示可回收利用,当该buf被新的buf指针指向的时候,就置1,
  • in_file:标志位,为1时表示这段缓冲区处理的是文件而不是内存,说明包体全部存入文件中,
  • flush:标志位,为1时表示需要执行flush操作 标示需要立即发送缓冲的所有数据;
  • sync:标志位,0同步,1异步
  • last_buf:标志位,表示是否是最后一块缓冲区,因为ngx_buf_t可以由ngx_chain_t链表串联起来,因此,当last_buf为1时,表示当前是最后一块待处理的缓冲区
  • last_in_chain:标志位,表示是否是ngx_chain_t中的最后一块缓冲区
  • last_shadow:标志位,表示是否是最后一个影子缓冲区,与shadow域配合使用。通常不建议使用它
  • temp_file:标志位,表示当前缓冲区是否属于临时文件
  • num:读取后端服务器包体分配的第几个buf
typedef void *            ngx_buf_tag_t;
typedef struct ngx_buf_s  ngx_buf_t;

struct ngx_buf_s {
    //它的pos成员和last成员指向的地址之间的内存就是接收到的还未解析的字符流
    u_char          *pos;
    u_char          *last;
    //处理文件时,file_pos与file_last的含义与处理内存时的pos与last相同,
    off_t            file_pos;
    off_t            file_last;
    //如果ngx_buf_t缓冲区用于内存,那么start指向这段内存的起始地址
    u_char          *start;
    u_char          *end;
    ngx_buf_tag_t    tag;
    ngx_file_t      *file;
    ngx_buf_t       *shadow;
    unsigned         temporary:1; 
    unsigned         memory:1;
    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;
};

ngx_chain_t

ngx_chain_t是与ngx_buf_t配合使用的链表数据结构

buf指向当前的ngx_buf_t缓冲区,next则用来指向下一个ngx_chain_t。如果这是最后一个ngx_chain_t,则需要把next置为NULL。

struct ngx_chain_s {
    ngx_buf_t    *buf;
    ngx_chain_t  *next;
};

标签:last,ngx,list,链表,Nginx,内存,数据结构,buf,底层
From: https://blog.csdn.net/weixin_50448879/article/details/136801820

相关文章

  • 解释nginx.conf.default 中关于fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_sc
    在nginx配置中,fastcgi_param指令用于定义传递给FastCGI服务器(如PHP-FPM)的参数。这些参数是FastCGI协议的一部分,用于在nginx和PHP-FPM之间传递关于请求的信息。在给出的配置片段中:nginxfastcgi_paramSCRIPT_FILENAME/scripts$fastcgi_script_name;这一行定义了一个FastCGI......
  • nginx 反向代理注意
    1.Nginx中正则捕获组在proxy_pass中不可用有一个需求,根据不同的路径代理到后端问题出在$1这个正则捕获组上。在Nginx中,正则表达式中的捕获组是根据()定义的,但这个捕获组只在location内部有效,并且不会传递到proxy_pass中。所以当你在proxy_pass中使用$1时,它实......
  • 数据结构学习第一天
    ......
  • Nginx服务启动失败
    问题描述:Nginx服务启动失败解决方案:查看是否有如下服务起来,有需要停止服务并改为手动SQLServer导致。其中很有可能是SQLServerReportingServices(MSSQLSERVER),它是SQLServer的日志系统。IIS服务。如果你电脑安装了这个,很有可能它在运行着,那么它就占用着80端口Worl......
  • nginx
    .配置文件路径:Nginx的配置文件通常位于/etc/nginx目录下。主要的配置文件是nginx.conf。2.静态文件配置:在nginx.conf文件中,可以通过server块来配置静态文件的访问。例如,可以添加以下配置来指定静态文件的根目录和访问路径server{listen80;server_nameexample.com;locati......
  • 数据结构(五)kmp---以题为例
    给定一个字符串 S,以及一个模式串 P,所有字符串中只包含大小写英文字母以及阿拉伯数字。模式串 P 在字符串 S 中多次作为子串出现。求出模式串 P 在字符串 S 中所有出现的位置的起始下标。输入格式第一行输入整数 N,表示字符串 P 的长度。第二行输入字符串 P。第......
  • 数据结构(四)队列1---以题为例
    给定一个大小为 n≤106的数组。有一个大小为 k 的滑动窗口,它从数组的最左边移动到最右边。你只能在窗口中看到 k 个数字。每次滑动窗口向右移动一个位置。以下是一个例子:该数组为 [13-1-35367],k为 3。窗口位置最小值最大值[13-1]-35367-1......
  • 树与二叉树(数据结构)
    本篇博客讲解树与二叉树,后续会继续讲解堆——————————————————————1.树概念及结构1.1树的概念 树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的......
  • 数据结构与算法-图
    引言        在计算机科学领域,数据结构和算法是程序员工具箱中的两大瑰宝。其中,图(Graph) 是一种极其重要的非线性数据结构,它以节点和边的概念描述实体间复杂的关系网络。本文将对图的数据结构进行详尽解析,探讨其基本概念、操作以及实际应用场景。一、什么是图?   ......
  • 如何查找访问 Nginx 的前 10 个 IP?
    在管理和维护Web服务器时,了解谁正在访问您的网站是非常重要的。Nginx是一个流行的Web服务器,通过分析其访问日志,您可以了解访问者的来源、频率以及他们的行为。有时候,您可能希望查找访问量最高的IP地址,以便进一步分析或采取措施,比如加强安全性或优化性能。本文将详细......