nginx-nginx数据结构

本篇文章主要记录说明使用nginx时,开辟一个简单http模块的时序图,还有nginx中封装的数据结构及其处理函数。

1.如何开发一个充满异步调用,无阻塞的http模块?

首先,我们需要把程序嵌如到nginx中(最终变异处的二进制程序nginx要包含我们的代码)。

然后,这个http模块要能介入到处理流程中。

在正式请求处理时,还要可以获取nginx框架定义的数据结构,解析后的用户请求信息

业务执行完毕后,则要考虑发送响应给用户(包括将磁盘中的文件以http包体的形式发送给用户)

我们都是讨论C/C++语言来进行编写,虽然nginx官方不倡导,本文章不讨论各个核心模块如何配合工作。

2.关于http模块的调用。

1.首先nginx是master和多个worker进程的组合,worket进程会在一个for循环语句例反复调用时间模块检测网络事件,即检测到TCP请求(接收到SYN包),将会为它建立TCP连接。

2.成功建立连接后根据nginx.conf文件中的配置会交由http框架处理。

ps:http框架会试图接收完整的HTTP头部,并在接收到完整的http头部后将请求的uri和nginx.conf里的location配置项的匹配来决定如何分发。

3.处理结束后会调用过滤模块,然后根据配置文件决定自己的行为。

时序图:

ps:需要注意HTTP框架到具体http模块间数据流的传递,还有之间的协同,以后会写到。

模块命名为:ngx_http_mytest_module.c

下面进入正题,所以下nginx中封装的数据类型还有数据结构

以下都为linux操作系统下的解释:

1.整形的封装:

 typedef intptr_t ngx_int_t; //代表int
 typedef uintptr_t ngx_uint_t; //代表unsinged int

2.数据结构:

1.字符串

//字符串的封装。其中data不是普通的字符串,很有可能不以‘0’结尾。必须配合len
  typedef struct{
      size_t len;
      u_char *data;   
 }ngx_str_t;  
 //用于字符串的比较函数,因为未必有0,所以必须用ngx_strncmp比较
 #define ngx_strncmp(s1,s2,n) strncmp((const char *)s1,(const char *)s2,n)

2.链表容器:

//这里封装的链表容器使用是很频繁,比如http头部就是使用这个数据结构来存储的。
    typedef struct ngx_list_part_s ngx_list_part_t;
    
    struct ngx_list_part_s
    {
        void            *elts;//数组的起始地址
        ngx_uint_t      nelts; //已经存在多少个元素,必须小于nalloc
        ngx_list_part_t *next; //下一个地址
    }
    
    typedef ngx_list_part_s
    {
        ngx_list_part_t *last;    //链表最后一个元素
        ngx_list_part_t part; //链表第一个数组元素
        size_t          size;    //每一个数组元素占用空间大小
        ngx_uint_t      nalloc;    //数组可以存储多少个数据
        ngx_pool_t      *poll;    //nginx内存池的对象。
    }ngx_list_t;
    
    //下面是封装的ngx_list_t的函数借口
    ngx_list_t *ngx_list_create(ngx_pool_t *pool,ngx_uint_t n,size_t size);//创建
    //返回创建链表地址。
    static ngx_inline ngx_int_t 
    ngx_list_init(ngx_list_t,ngx_pool_t *pool,ngx_uint_t n,size_t size); //初始化
    //返回NGX_OK,    NGX_ERROR;
    void *ngx_list_push(ngx_list_t *list);//添加元素、
    
    //遍历链表
    ngx_list_part_t *part = &testlist.part;
    ngx_str_t = part->elts;
    for(i = 0;;i++)
    {
        if(i >= part->nelts)
        {
            if(part->next = NULL)
                break;
            part = part->next;
            header = part->elts;
            i = 0 ;
        }
        printf("%*s\n",str[i].len,str[i].data);
    }

3.key/value (用于存储http头部信息)

    typedef struct
    {
        ngx_uint_t hash;
        ngx_str_t key;
        ngx_str_t value;
        u_char*   lowcase_key; //全是小写的key字符串。
    }ngax_table_elt_t;

4.缓冲区的数据结构

typedef struct ngx_buf_s ngx_buf_t;
typedef void *           ngx_buf_tag_t;
struct  ngx_buf_s{
    u_char *pos;    //数据处理的开始位置;
    u_char *last;    //数据处理的结束位置;
    off_t     file_pos; //处理文件的文件开始位置
    off_t    file_last;    //处理文件的文件结束位置
    u_char    *start;    //如果ngx_buf_t用于内存,那么指向这个内存的起始地址
    u_char    *end;    //缓冲区内存的末尾
    ngx_buf_tag_t tag;    //缓冲区类型
    ngx_file_t    *file;    //引用的文件
    ngx_buf_t    *shadow;    //影子缓冲区,很少用,设计复杂,简单理解为多个指向同一块内存
    unsigned    temporary:1;    //临时内存标志位,1表示这段内存可以修改
    unsigned    memory:1;    //标志位,为1表示数据在内存中且内存不可以修改
    unsigned    mmap:1;    //1表示这顿啊内存用mmap系统调用映射过来的,不可以被修改
    unsigned    recycled:1;    //1表示可以回收
    unsigned    in_file:1;    //1表示这段缓冲区处理的是文件而不是内存
    unsigned    flush:1;    //1表示需要执行flush操作
    unsigned    sync:1;    //是否需要使用同步方式
    unsigned    last_buf:1;    //表示是否为最后一块缓冲区
    unsigned    last_in_chain:1;    //表示是否是ngx_chain_t中的最后一块缓冲区
    unsigned    last_shadow:1;    //是否是最后一个影子缓冲区,与shadow域配合使用。不建议使用
    unsigned    temp_file:1;    //表示当前缓冲去是否是临时文件
}

5.ngx_chain_t(与ngx_buf_t配合使用,存储向用户发送的HTTP包体,结尾设置为null)

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

以上就是nginx的数据结构。

时间: 2024-11-04 13:55:56

nginx-nginx数据结构的相关文章

[nginx] nginx源码分析--健康检查模块锁分析

健康检查模块 见前文:[nginx] nginx源码分析--健康检查模块 其中有一张框架图, 接下来的内容,将会利用到这个图中的内容. [classic_tong @ https:////www.cnblogs.com/hugetong/p/12274125.html ]  描述 我们知道nginx是多进程的,每个进程都保存了相同的配置.但是实际上, 并不需要每一个进程对每一个后端服务器进行. 于是健康检查模块在这里需要一个进程间同步机制,用来协商哪一个进程对 哪一个后端服务器进行检查. 接下来

nginx配置失败,卸载后重装出问题 awk: cannot open /etc/nginx/nginx.conf (No such file or directory)

nginx配置失败,卸载后重装出问题 [email protected]:~$ sudo apt-get install nginx 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 将会安装下列额外的软件包: nginx-common nginx-core 建议安装的软件包: fcgiwrap nginx-doc 下列[新]软件包将被安装: nginx nginx-common nginx-core 升级了 0 个软件包,新安装了 3 个软件包,要卸载

Starting nginx: nginx: [emerg] bind() to 0.0.0.0:8088 failed (13: Permission denied) nginx 启动失败

Starting nginx: nginx: [emerg] bind() to 0.0.0.0:8088 failed (13: Permission denied) nginx 启动失败,日志里面报错信息如下: Starting nginx: nginx: [emerg] bind() to 0.0.0.0:8088 failed (13: Permission denied) 权限拒绝,经检查发现是开启selinux 导致的. 直接关闭 getenforce   这个命令可以查看当前是否开

Ubuntu 重启 Nginx 失败,* Restarting nginx nginx ...fail!

原因是你配置 nginx 的配置文件出了错误 查找错误,处理方法: $ sudo nginx -t nginx: [emerg] "location" directive is not allowed here in /etc/nginx/nginx.conf:11 nginx: configuration file /etc/nginx/nginx.conf test failed1 根据错误信息,修改对应生的配置文件即可. 转自: http://www.linuxidc.com/L

初识Nginx——nginx的编译、安装及特点(一)

一.Nginx简介 nginx是一个轻量级的服务器软件,目前世界排名第三,第一占据大部分的市场份额的是apache,第二的是微软公司的IIS站的比重大约是23%.nginx自开发出来04年公布出来市场份额逐年上升,所拥有的功能是前两者都没有的,而且还能与之互补,所以很有必要认真研究一番. Nginx是一款web服务器反向代理服务器及电子邮件代理服务器.是在BSD-like协议下发行的. Nginx最突出的特点就是占有内存少,并发能力强.Nginx采用的是事件驱动结构,使用异步套接字来接受客户的请

nginx: [error] invalid PID number “” in “/usr/local/var/run/nginx/nginx.pid”

在Mac上用brew安装Nginx,然后修改Nginx配置文件,再重启时报出如下错误: nginx: [error] invalid PID number "" in "/usr/local/var/run/nginx/nginx.pid" 解决办法: $ sudo nginx -c /usr/local/etc/nginx/nginx.conf $ sudo nginx -s reload

nginx nginx.pid无故文件丢失,日志无法正常轮转

nginx.pid文件丢失,日志无法正常轮转.解决方法:故障原因,日志被迁移后,kill-USR1 pid 没有成功,致使nginx写的文件句柄还是在旧的文件里. 模拟故障:1: 我们 mv 日志文件为.bak2: 我们清空nginx.pid文件3: 我们试图reload的时候失败,因为pid文件是空的.这时候我们使用killall nginx ,然后再启动nginx才能解决. [[email protected] nginx]# ps -ef |grep nginx root     1028

nginx: [error] open() "/var/run/nginx/nginx.pid" failed (2: No such file or directory)

在重启nginx服务的时候,出现了这个错误. [[email protected] etc]# nginx -c /var/run/nginx/nginx.pid nginx: [emerg] open() "/var/run/nginx/nginx.pid" failed (2: No such file or directory) 解决办法: [[email protected] etc]# nginx -c /etc/nginx/nginx.conf 其他的一些解决办法: 1.进

nginx 启动报错 “/var/run/nginx/nginx.pid" failed” 解决方法

参考:https://www.cnblogs.com/yufeng218/p/8215421.html 问题描述: 重启Nginx报错, nginx: [emerg] open() "/var/run/nginx/nginx.pid" failed (2: No such file or directory). 解决方法: 第一步.在 /usr/local/nginx 目录下创建 logs 目录:mkdir /usr/local/nginx/logs 第二步.进入 cd /usr/lo

[nginx]nginx的一个奇葩问题 500 Internal Server Error phpstudy2018

[nginx]nginx的一个奇葩问题 500 Internal Server Error 解决方案 nginx 一直报500 Internal Server Error 错误,配置是通过phpstudy2018站点域名管理生成的. 默认是  root   "D:\php\phpstudy\PHPTutorial\WWW\foxphp"; 修改成这样就好了 root   "D:\\php\\phpstudy\\PHPTutorial\\WWW\\foxphp"; 查