Nginx 关键数据结构和继承关系分析

1. 概述

Nginx采用C语言开发,通过精心设计的数据结构实现了高效的内存管理、快速的数据访问和灵活的模块化架构。本文档深入分析Nginx中的关键数据结构及其相互关系。

2. 数据结构继承关系图

classDiagram
    class ngx_cycle_t {
        +pool: ngx_pool_t*
        +log: ngx_log_t*
        +modules: ngx_module_t**
        +conf_ctx: void****
        +connections: ngx_connection_t*
        +listening: ngx_array_t
        +paths: ngx_array_t
        +open_files: ngx_list_t
        +shared_memory: ngx_list_t
    }

    class ngx_module_t {
        +ctx_index: ngx_uint_t
        +index: ngx_uint_t
        +name: char*
        +ctx: void*
        +commands: ngx_command_t*
        +type: ngx_uint_t
        +init_master(): ngx_int_t
        +init_module(): ngx_int_t
        +init_process(): ngx_int_t
        +exit_process(): void
    }

    class ngx_connection_t {
        +data: void*
        +read: ngx_event_t*
        +write: ngx_event_t*
        +fd: ngx_socket_t
        +recv: ngx_recv_pt
        +send: ngx_send_pt
        +pool: ngx_pool_t*
        +log: ngx_log_t*
        +sockaddr: struct sockaddr*
        +listening: ngx_listening_t*
    }

    class ngx_event_t {
        +data: void*
        +handler: ngx_event_handler_pt
        +write: unsigned
        +accept: unsigned
        +active: unsigned
        +ready: unsigned
        +timer: ngx_rbtree_node_t
        +queue: ngx_queue_t
    }

    class ngx_http_request_t {
        +connection: ngx_connection_t*
        +ctx: void**
        +main_conf: void**
        +srv_conf: void**
        +loc_conf: void**
        +pool: ngx_pool_t*
        +headers_in: ngx_http_headers_in_t
        +headers_out: ngx_http_headers_out_t
        +request_body: ngx_http_request_body_t*
        +upstream: ngx_http_upstream_t*
    }

    class ngx_pool_t {
        +d: ngx_pool_data_t
        +max: size_t
        +current: ngx_pool_t*
        +chain: ngx_chain_t*
        +large: ngx_pool_large_t*
        +cleanup: ngx_pool_cleanup_t*
        +log: ngx_log_t*
    }

    class ngx_buf_t {
        +pos: u_char*
        +last: u_char*
        +file_pos: off_t
        +file_last: off_t
        +start: u_char*
        +end: u_char*
        +tag: ngx_buf_tag_t
        +file: ngx_file_t*
        +shadow: ngx_buf_t*
        +temporary: unsigned
        +memory: unsigned
        +mmap: unsigned
        +recycled: unsigned
        +in_file: unsigned
        +flush: unsigned
        +sync: unsigned
        +last_buf: unsigned
        +last_in_chain: unsigned
    }

    ngx_cycle_t ||--o{ ngx_module_t
    ngx_cycle_t ||--o{ ngx_connection_t
    ngx_connection_t ||--|| ngx_event_t : read
    ngx_connection_t ||--|| ngx_event_t : write
    ngx_connection_t ||--|| ngx_pool_t
    ngx_http_request_t ||--|| ngx_connection_t
    ngx_http_request_t ||--|| ngx_pool_t
    ngx_pool_t ||--o{ ngx_buf_t

3. 核心数据结构详解

3.1 ngx_cycle_t - 全局周期结构

struct ngx_cycle_s {
    void                  ****conf_ctx;      // 配置上下文数组
    ngx_pool_t               *pool;          // 全局内存池
    
    ngx_log_t                *log;           // 主日志对象
    ngx_log_t                 new_log;       // 新日志对象
    
    ngx_uint_t                log_use_stderr; // 使用stderr标志
    
    ngx_connection_t        **files;         // 文件连接数组
    ngx_connection_t         *free_connections; // 空闲连接链表
    ngx_uint_t                free_connection_n; // 空闲连接数量
    
    ngx_module_t            **modules;       // 模块数组
    ngx_uint_t                modules_n;     // 模块数量
    ngx_uint_t                modules_used;  // 模块使用标志
    
    ngx_queue_t               reusable_connections_queue; // 可复用连接队列
    ngx_uint_t                reusable_connections_n;     // 可复用连接数量
    time_t                    connections_reuse_time;     // 连接复用时间
    
    ngx_array_t               listening;     // 监听端口数组
    ngx_array_t               paths;         // 路径数组
    
    ngx_array_t               config_dump;   // 配置转储数组
    ngx_rbtree_t              config_dump_rbtree;    // 配置转储红黑树
    ngx_rbtree_node_t         config_dump_sentinel;  // 配置转储哨兵
    
    ngx_list_t                open_files;    // 打开文件链表
    ngx_list_t                shared_memory; // 共享内存链表
    
    ngx_uint_t                connection_n;  // 连接总数
    ngx_uint_t                files_n;       // 文件总数
    
    ngx_connection_t         *connections;   // 连接数组
    ngx_event_t              *read_events;   // 读事件数组
    ngx_event_t              *write_events;  // 写事件数组
    
    ngx_cycle_t              *old_cycle;     // 旧周期对象
    
    ngx_str_t                 conf_file;     // 配置文件路径
    ngx_str_t                 conf_param;    // 配置参数
    ngx_str_t                 conf_prefix;   // 配置前缀
    ngx_str_t                 prefix;        // 安装前缀
    ngx_str_t                 error_log;     // 错误日志路径
    ngx_str_t                 lock_file;     // 锁文件路径
    ngx_str_t                 hostname;      // 主机名
};

功能说明:

  • 全局配置和状态管理中心
  • 管理所有模块、连接、事件等资源
  • 提供配置热重载支持
  • 维护系统运行时状态

3.2 ngx_module_t - 模块结构

struct ngx_module_s {
    ngx_uint_t            ctx_index;         // 上下文索引
    ngx_uint_t            index;             // 模块索引
    
    char                 *name;              // 模块名称
    
    ngx_uint_t            spare0;            // 保留字段
    ngx_uint_t            spare1;            // 保留字段
    
    ngx_uint_t            version;           // 模块版本
    const char           *signature;         // 模块签名
    
    void                 *ctx;               // 模块上下文
    ngx_command_t        *commands;          // 指令数组
    ngx_uint_t            type;              // 模块类型
    
    // 生命周期回调函数
    ngx_int_t           (*init_master)(ngx_log_t *log);
    ngx_int_t           (*init_module)(ngx_cycle_t *cycle);
    ngx_int_t           (*init_process)(ngx_cycle_t *cycle);
    ngx_int_t           (*init_thread)(ngx_cycle_t *cycle);
    void                (*exit_thread)(ngx_cycle_t *cycle);
    void                (*exit_process)(ngx_cycle_t *cycle);
    void                (*exit_master)(ngx_cycle_t *cycle);
    
    uintptr_t             spare_hook0;       // 保留钩子
    uintptr_t             spare_hook1;       // 保留钩子
    uintptr_t             spare_hook2;       // 保留钩子
    uintptr_t             spare_hook3;       // 保留钩子
    uintptr_t             spare_hook4;       // 保留钩子
    uintptr_t             spare_hook5;       // 保留钩子
    uintptr_t             spare_hook6;       // 保留钩子
    uintptr_t             spare_hook7;       // 保留钩子
};

模块类型定义:

#define NGX_CORE_MODULE      0x45524F43  /* "CORE" */
#define NGX_CONF_MODULE      0x464E4F43  /* "CONF" */
#define NGX_EVENT_MODULE     0x544E5645  /* "EVNT" */
#define NGX_HTTP_MODULE      0x50545448  /* "HTTP" */
#define NGX_MAIL_MODULE      0x4C49414D  /* "MAIL" */
#define NGX_STREAM_MODULE    0x4D525453  /* "STRM" */

3.3 ngx_connection_t - 连接结构

struct ngx_connection_s {
    void               *data;                // 连接关联数据
    ngx_event_t        *read;                // 读事件
    ngx_event_t        *write;               // 写事件
    
    ngx_socket_t        fd;                  // 套接字描述符
    
    ngx_recv_pt         recv;                // 接收函数指针
    ngx_send_pt         send;                // 发送函数指针
    ngx_recv_chain_pt   recv_chain;          // 接收链函数指针
    ngx_send_chain_pt   send_chain;          // 发送链函数指针
    
    ngx_listening_t    *listening;           // 监听结构
    
    off_t               sent;                // 已发送字节数
    
    ngx_log_t          *log;                 // 连接日志
    
    ngx_pool_t         *pool;                // 连接内存池
    
    int                 type;                // 连接类型
    struct sockaddr    *sockaddr;            // 套接字地址
    socklen_t           socklen;             // 地址长度
    ngx_str_t           addr_text;           // 地址文本表示
    
    ngx_proxy_protocol_t  *proxy_protocol;  // 代理协议
    
#if (NGX_SSL || NGX_COMPAT)
    ngx_ssl_connection_t  *ssl;              // SSL连接
#endif
    
    ngx_udp_connection_t  *udp;              // UDP连接
    
    struct sockaddr    *local_sockaddr;      // 本地地址
    socklen_t           local_socklen;       // 本地地址长度
    
    ngx_buf_t          *buffer;              // 接收缓冲区
    
    ngx_queue_t         queue;               // 队列节点
    
    ngx_atomic_uint_t   number;              // 连接编号
    
    ngx_msec_t          start_time;          // 开始时间
    ngx_uint_t          requests;            // 请求数量
    
    unsigned            buffered:8;          // 缓冲标志
    
    unsigned            log_error:3;         // 日志错误级别
    
    unsigned            timedout:1;          // 超时标志
    unsigned            error:1;             // 错误标志
    unsigned            destroyed:1;         // 销毁标志
    unsigned            pipeline:1;          // 管道标志
    
    unsigned            idle:1;              // 空闲标志
    unsigned            reusable:1;          // 可复用标志
    unsigned            close:1;             // 关闭标志
    unsigned            shared:1;            // 共享标志
    
    unsigned            sendfile:1;          // sendfile标志
    unsigned            sndlowat:1;          // 发送低水位标志
    unsigned            tcp_nodelay:2;       // TCP_NODELAY标志
    unsigned            tcp_nopush:2;        // TCP_NOPUSH标志
    
    unsigned            need_last_buf:1;     // 需要最后缓冲区标志
    
#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT)
    unsigned            busy_count:2;        // 忙计数
#endif
    
#if (NGX_THREADS || NGX_COMPAT)
    ngx_thread_task_t  *sendfile_task;       // sendfile任务
#endif
};

3.4 ngx_event_t - 事件结构

struct ngx_event_s {
    void            *data;                   // 事件数据
    
    unsigned         write:1;                // 写事件标志
    unsigned         accept:1;               // 接受连接标志
    unsigned         instance:1;             // 实例标志
    unsigned         active:1;               // 激活标志
    unsigned         disabled:1;             // 禁用标志
    unsigned         ready:1;                // 就绪标志
    unsigned         oneshot:1;              // 一次性标志
    unsigned         complete:1;             // 完成标志
    
    unsigned         eof:1;                  // 文件结束标志
    unsigned         error:1;                // 错误标志
    
    unsigned         timedout:1;             // 超时标志
    unsigned         timer_set:1;            // 定时器设置标志
    
    unsigned         delayed:1;              // 延迟标志
    unsigned         deferred_accept:1;      // 延迟接受标志
    unsigned         pending_eof:1;          // 待处理EOF标志
    unsigned         posted:1;               // 已投递标志
    unsigned         closed:1;               // 关闭标志
    
    unsigned         channel:1;              // 通道标志
    unsigned         resolver:1;             // 解析器标志
    unsigned         cancelable:1;           // 可取消标志
    
#if (NGX_HAVE_KQUEUE)
    unsigned         kq_vnode:1;             // kqueue vnode标志
    int              kq_errno;               // kqueue错误码
#endif
    
    int              available;              // 可用数据量
    
    ngx_event_handler_pt  handler;           // 事件处理函数
    
#if (NGX_HAVE_IOCP)
    ngx_event_ovlp_t ovlp;                   // IOCP重叠结构
#endif
    
    ngx_uint_t       index;                  // 事件索引
    
    ngx_log_t       *log;                    // 事件日志
    
    ngx_rbtree_node_t   timer;               // 定时器节点
    ngx_queue_t         queue;               // 队列节点
};

3.5 ngx_http_request_t - HTTP请求结构

struct ngx_http_request_s {
    uint32_t                          signature;         // 签名 "HTTP"
    
    ngx_connection_t                 *connection;        // 连接对象
    
    void                            **ctx;               // 模块上下文数组
    void                            **main_conf;         // 主配置数组
    void                            **srv_conf;          // 服务器配置数组
    void                            **loc_conf;          // 位置配置数组
    
    ngx_http_event_handler_pt         read_event_handler;  // 读事件处理器
    ngx_http_event_handler_pt         write_event_handler; // 写事件处理器
    
#if (NGX_HTTP_CACHE)
    ngx_http_cache_t                 *cache;             // 缓存对象
#endif
    
    ngx_http_upstream_t              *upstream;          // 上游对象
    ngx_array_t                      *upstream_states;   // 上游状态数组
    
    ngx_pool_t                       *pool;              // 请求内存池
    ngx_buf_t                        *header_in;         // 请求头缓冲区
    
    ngx_http_headers_in_t             headers_in;        // 请求头
    ngx_http_headers_out_t            headers_out;       // 响应头
    
    ngx_http_request_body_t          *request_body;      // 请求体
    
    time_t                            lingering_time;    // 延迟关闭时间
    time_t                            start_sec;         // 开始秒数
    ngx_msec_t                        start_msec;        // 开始毫秒数
    
    ngx_uint_t                        method;            // HTTP方法
    ngx_uint_t                        http_version;      // HTTP版本
    
    ngx_str_t                         request_line;      // 请求行
    ngx_str_t                         uri;               // URI
    ngx_str_t                         args;              // 参数
    ngx_str_t                         exten;             // 扩展名
    ngx_str_t                         unparsed_uri;      // 未解析URI
    
    ngx_str_t                         method_name;       // 方法名
    ngx_str_t                         http_protocol;     // HTTP协议
    ngx_str_t                         schema;            // 协议模式
    
    ngx_chain_t                      *out;               // 输出链
    ngx_http_request_t               *main;              // 主请求
    ngx_http_request_t               *parent;            // 父请求
    ngx_http_postponed_request_t     *postponed;         // 延迟请求
    ngx_http_post_subrequest_t       *post_subrequest;   // 子请求后处理
    
    ngx_http_posted_request_t        *posted_requests;   // 投递请求
    
    ngx_int_t                         phase_handler;     // 阶段处理器索引
    ngx_http_handler_pt               content_handler;   // 内容处理器
    
    ngx_uint_t                        access_code;       // 访问代码
    
    ngx_http_variable_value_t        *variables;         // 变量数组
    
#if (NGX_PCRE)
    ngx_uint_t                        ncaptures;         // 捕获数量
    int                              *captures;          // 捕获数组
    u_char                           *captures_data;     // 捕获数据
#endif
    
    size_t                            limit_rate;        // 限速
    size_t                            limit_rate_after;  // 限速后
    
    /* used to learn the Apache compatible response length without a header */
    size_t                            header_size;       // 头部大小
    
    off_t                             request_length;    // 请求长度
    
    ngx_uint_t                        err_status;        // 错误状态
    ngx_http_connection_t            *http_connection;   // HTTP连接
    
    ngx_http_log_handler_pt           log_handler;       // 日志处理器
    
    ngx_http_cleanup_t               *cleanup;           // 清理链表
    
    unsigned                          count:16;          // 引用计数
    unsigned                          subrequests:8;     // 子请求数量
    unsigned                          blocked:8;         // 阻塞计数
    
    unsigned                          aio:1;             // AIO标志
    
    unsigned                          http_state:4;      // HTTP状态
    
    /* URI with "/." and on Win32 with "//" */
    unsigned                          complex_uri:1;     // 复杂URI标志
    
    /* URI with "%" */
    unsigned                          quoted_uri:1;      // 引用URI标志
    
    /* URI with "+" */
    unsigned                          plus_in_uri:1;     // URI中有+号标志
    
    /* URI with " " */
    unsigned                          space_in_uri:1;    // URI中有空格标志
    
    unsigned                          invalid_header:1;  // 无效头部标志
    
    unsigned                          add_uri_to_alias:1; // 添加URI到别名标志
    unsigned                          valid_location:1;   // 有效位置标志
    unsigned                          valid_unparsed_uri:1; // 有效未解析URI标志
    unsigned                          uri_changed:1;      // URI改变标志
    unsigned                          uri_changes:4;      // URI改变次数
    
    unsigned                          request_body_in_single_buf:1;     // 请求体在单个缓冲区标志
    unsigned                          request_body_in_file_only:1;      // 请求体仅在文件标志
    unsigned                          request_body_in_persistent_file:1; // 请求体在持久文件标志
    unsigned                          request_body_in_clean_file:1;     // 请求体在清理文件标志
    unsigned                          request_body_file_group_access:1; // 请求体文件组访问标志
    unsigned                          request_body_file_log_level:3;    // 请求体文件日志级别
    unsigned                          request_body_no_buffering:1;      // 请求体无缓冲标志
    
    unsigned                          subrequest_in_memory:1;           // 子请求在内存标志
    unsigned                          waited:1;                         // 等待标志
    
#if (NGX_HTTP_CACHE)
    unsigned                          cached:1;                         // 缓存标志
#endif
    
#if (NGX_HTTP_GZIP)
    unsigned                          gzip_tested:1;                    // gzip测试标志
    unsigned                          gzip_ok:1;                        // gzip可用标志
    unsigned                          gzip_vary:1;                      // gzip变化标志
#endif
    
#if (NGX_PCRE)
    unsigned                          realloc_captures:1;               // 重新分配捕获标志
#endif
    
    unsigned                          proxy:1;                          // 代理标志
    unsigned                          bypass_cache:1;                   // 绕过缓存标志
    unsigned                          no_cache:1;                       // 无缓存标志
    
    /*
     * instead of using the request context data in
     * ngx_http_limit_conn_module and ngx_http_limit_req_module
     * we use the single bits in the request structure
     */
    unsigned                          limit_conn_status:2;              // 连接限制状态
    unsigned                          limit_req_status:3;               // 请求限制状态
    
    unsigned                          limit_rate_set:1;                 // 限速设置标志
    unsigned                          limit_rate_after_set:1;           // 限速后设置标志
    
#if 0
    unsigned                          cacheable:1;                      // 可缓存标志
#endif
    
    unsigned                          pipeline:1;                       // 管道标志
    unsigned                          chunked:1;                        // 分块标志
    unsigned                          header_only:1;                    // 仅头部标志
    unsigned                          expect_trailers:1;                // 期望尾部标志
    unsigned                          keepalive:1;                      // 保持连接标志
    unsigned                          lingering_close:1;                // 延迟关闭标志
    
    unsigned                          discard_body:1;                   // 丢弃体标志
    unsigned                          reading_body:1;                   // 读取体标志
    unsigned                          internal:1;                       // 内部标志
    unsigned                          error_page:1;                     // 错误页面标志
    unsigned                          filter_finalize:1;                // 过滤器完成标志
    unsigned                          post_action:1;                    // 后动作标志
    unsigned                          request_complete:1;               // 请求完成标志
    unsigned                          request_output:1;                 // 请求输出标志
    unsigned                          header_sent:1;                    // 头部已发送标志
    unsigned                          expect_tested:1;                  // 期望测试标志
    unsigned                          root:1;                           // 根标志
    unsigned                          lowercase:1;                      // 小写标志
    unsigned                          file_ranges:1;                    // 文件范围标志
    unsigned                          allow_ranges:1;                   // 允许范围标志
    unsigned                          single_range:1;                   // 单一范围标志
    unsigned                          disable_not_modified:1;           // 禁用未修改标志
    unsigned                          stat_reading:1;                   // 统计读取标志
    unsigned                          stat_writing:1;                   // 统计写入标志
    unsigned                          stat_processing:1;                // 统计处理标志
    
    unsigned                          background:1;                     // 后台标志
    unsigned                          health_check:1;                   // 健康检查标志
};

4. 内存管理数据结构

4.1 ngx_pool_t - 内存池结构

typedef struct {
    u_char               *last;              // 当前分配位置
    u_char               *end;               // 池结束位置
    ngx_pool_t           *next;              // 下一个池
    ngx_uint_t            failed;            // 失败次数
} ngx_pool_data_t;

struct ngx_pool_s {
    ngx_pool_data_t       d;                 // 池数据
    size_t                max;               // 最大分配大小
    ngx_pool_t           *current;           // 当前池
    ngx_chain_t          *chain;             // 缓冲区链
    ngx_pool_large_t     *large;             // 大块内存链表
    ngx_pool_cleanup_t   *cleanup;           // 清理函数链表
    ngx_log_t            *log;               // 日志对象
};

// 大块内存结构
struct ngx_pool_large_s {
    ngx_pool_large_t     *next;              // 下一个大块
    void                 *alloc;             // 分配的内存
};

// 清理函数结构
struct ngx_pool_cleanup_s {
    ngx_pool_cleanup_pt   handler;           // 清理函数
    void                 *data;              // 清理数据
    ngx_pool_cleanup_t   *next;              // 下一个清理函数
};

4.2 ngx_buf_t - 缓冲区结构

struct ngx_buf_s {
    u_char          *pos;                    // 数据开始位置
    u_char          *last;                   // 数据结束位置
    off_t            file_pos;               // 文件开始位置
    off_t            file_last;              // 文件结束位置
    
    u_char          *start;                  // 缓冲区开始
    u_char          *end;                    // 缓冲区结束
    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;                 // mmap缓冲区
    
    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;                    // 调试用编号
};

// 缓冲区链结构
struct ngx_chain_s {
    ngx_buf_t    *buf;                       // 缓冲区
    ngx_chain_t  *next;                      // 下一个链节点
};

5. 容器数据结构

5.1 ngx_array_t - 动态数组

typedef struct {
    void        *elts;                       // 元素数组
    ngx_uint_t   nelts;                      // 元素个数
    size_t       size;                       // 元素大小
    ngx_uint_t   nalloc;                     // 分配的元素个数
    ngx_pool_t  *pool;                       // 内存池
} ngx_array_t;

特点:

  • 动态扩容,自动管理内存
  • 元素类型固定,大小统一
  • 基于内存池分配,无需手动释放
  • 支持快速随机访问

5.2 ngx_list_t - 链表

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;

特点:

  • 分段存储,减少内存碎片
  • 只支持尾部插入
  • 适合存储大量同类型数据
  • 遍历效率高

5.3 ngx_hash_t - 哈希表

typedef struct {
    ngx_hash_elt_t  **buckets;               // 桶数组
    ngx_uint_t        size;                  // 桶的个数
} ngx_hash_t;

typedef struct {
    void             *value;                 // 值
    u_short           len;                   // 键长度
    u_char            name[1];               // 键名称
} ngx_hash_elt_t;

// 哈希表初始化结构
typedef struct {
    ngx_hash_t       *hash;                  // 哈希表
    ngx_hash_key_pt   key;                   // 哈希函数
    
    ngx_uint_t        max_size;              // 最大大小
    ngx_uint_t        bucket_size;           // 桶大小
    
    char             *name;                  // 名称
    ngx_pool_t       *pool;                  // 内存池
    ngx_pool_t       *temp_pool;             // 临时内存池
} ngx_hash_init_t;

特点:

  • 开放寻址法解决冲突
  • 静态哈希表,构建后不可修改
  • 查找效率O(1)
  • 适合配置数据存储

5.4 ngx_rbtree_t - 红黑树

typedef ngx_uint_t  ngx_rbtree_key_t;
typedef ngx_int_t   ngx_rbtree_key_int_t;

typedef struct ngx_rbtree_node_s  ngx_rbtree_node_t;

struct ngx_rbtree_node_s {
    ngx_rbtree_key_t       key;              // 键值
    ngx_rbtree_node_t     *left;             // 左子树
    ngx_rbtree_node_t     *right;            // 右子树
    ngx_rbtree_node_t     *parent;           // 父节点
    u_char                 color;            // 节点颜色
    u_char                 data;             // 节点数据
};

typedef struct ngx_rbtree_s  ngx_rbtree_t;

typedef void (*ngx_rbtree_insert_pt) (ngx_rbtree_node_t *root,
    ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);

struct ngx_rbtree_s {
    ngx_rbtree_node_t     *root;             // 根节点
    ngx_rbtree_node_t     *sentinel;         // 哨兵节点
    ngx_rbtree_insert_pt   insert;           // 插入函数
};

特点:

  • 自平衡二叉搜索树
  • 查找、插入、删除时间复杂度O(log n)
  • 用于定时器管理、缓存索引等
  • 支持范围查询

5.5 ngx_queue_t - 双向链表队列

typedef struct ngx_queue_s  ngx_queue_t;

struct ngx_queue_s {
    ngx_queue_t  *prev;                      // 前一个节点
    ngx_queue_t  *next;                      // 后一个节点
};

特点:

  • 侵入式双向链表
  • 不存储数据,只维护链接关系
  • 插入删除操作O(1)
  • 适合实现各种队列和链表

6. 字符串和I/O数据结构

6.1 ngx_str_t - 字符串结构

typedef struct {
    size_t      len;                         // 字符串长度
    u_char     *data;                        // 字符串数据
} ngx_str_t;

// 字符串操作宏
#define ngx_string(str)     { sizeof(str) - 1, (u_char *) str }
#define ngx_null_string     { 0, NULL }
#define ngx_str_set(str, text)                                               \
    (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text
#define ngx_str_null(str)   (str)->len = 0; (str)->data = NULL

特点:

  • 二进制安全,支持包含’\0’的字符串
  • 长度和数据分离存储
  • 避免strlen()调用,提高性能
  • 支持字符串切片操作

6.2 ngx_file_t - 文件结构

struct ngx_file_s {
    ngx_fd_t                   fd;           // 文件描述符
    ngx_str_t                  name;         // 文件名
    ngx_file_info_t            info;         // 文件信息
    
    off_t                      offset;       // 文件偏移
    off_t                      sys_offset;   // 系统偏移
    
    ngx_log_t                 *log;          // 日志对象
    
#if (NGX_THREADS || NGX_COMPAT)
    ngx_int_t                (*thread_handler)(ngx_thread_task_t *task,
                                               ngx_file_t *file);
    void                      *thread_ctx;   // 线程上下文
    ngx_thread_task_t         *thread_task;  // 线程任务
#endif
    
#if (NGX_HAVE_FILE_AIO || NGX_COMPAT)
    ngx_event_aio_t           *aio;          // AIO事件
#endif
    
    unsigned                   valid_info:1; // 有效信息标志
    unsigned                   directio:1;   // 直接I/O标志
};

7. 数据结构关系图

7.1 内存管理关系

graph TB
    subgraph "Memory Management"
        A[ngx_cycle_t] --> B[ngx_pool_t]
        B --> C[ngx_pool_data_t]
        B --> D[ngx_pool_large_t]
        B --> E[ngx_pool_cleanup_t]
        
        F[ngx_connection_t] --> G[ngx_pool_t]
        H[ngx_http_request_t] --> I[ngx_pool_t]
        
        J[ngx_buf_t] --> K[ngx_chain_t]
        K --> L[ngx_buf_t]
    end

7.2 事件和连接关系

graph TB
    subgraph "Event and Connection"
        A[ngx_connection_t] --> B[ngx_event_t read]
        A --> C[ngx_event_t write]
        
        D[ngx_http_request_t] --> A
        
        E[ngx_cycle_t] --> F[ngx_connection_t* connections]
        E --> G[ngx_event_t* read_events]
        E --> H[ngx_event_t* write_events]
        
        I[ngx_rbtree_t timer_tree] --> J[ngx_event_t timer]
        K[ngx_queue_t posted_events] --> L[ngx_event_t queue]
    end

7.3 模块和配置关系

graph TB
    subgraph "Module and Configuration"
        A[ngx_cycle_t] --> B[ngx_module_t** modules]
        A --> C[void**** conf_ctx]
        
        D[ngx_module_t] --> E[ngx_command_t* commands]
        D --> F[void* ctx]
        
        G[ngx_http_request_t] --> H[void** main_conf]
        G --> I[void** srv_conf]
        G --> J[void** loc_conf]
    end

8. 数据结构使用模式

8.1 RAII模式 (Resource Acquisition Is Initialization)

// 内存池自动管理资源
ngx_pool_t *pool = ngx_create_pool(4096, log);

// 从池中分配的内存无需手动释放
char *buffer = ngx_palloc(pool, 1024);
ngx_array_t *array = ngx_array_create(pool, 10, sizeof(ngx_str_t));

// 注册清理函数
ngx_pool_cleanup_t *cln = ngx_pool_cleanup_add(pool, 0);
cln->handler = cleanup_function;
cln->data = cleanup_data;

// 销毁池时自动释放所有资源
ngx_destroy_pool(pool);

8.2 对象池模式

// 连接池预分配连接对象
cycle->connections = ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n,
                               cycle->log);
cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
                               cycle->log);
cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
                                cycle->log);

// 建立连接和事件的对应关系
for (i = 0; i < cycle->connection_n; i++) {
    cycle->connections[i].read = &cycle->read_events[i];
    cycle->connections[i].write = &cycle->write_events[i];
    cycle->read_events[i].data = &cycle->connections[i];
    cycle->write_events[i].data = &cycle->connections[i];
}

8.3 侵入式容器模式

// 结构体包含队列节点
typedef struct {
    ngx_queue_t   queue;    // 队列节点
    ngx_str_t     name;     // 实际数据
    ngx_uint_t    value;    // 实际数据
} my_data_t;

// 插入队列
my_data_t *data = ngx_palloc(pool, sizeof(my_data_t));
ngx_queue_insert_tail(&queue_head, &data->queue);

// 从队列节点获取数据
ngx_queue_t *q = ngx_queue_head(&queue_head);
my_data_t *data = ngx_queue_data(q, my_data_t, queue);

9. 性能优化设计

9.1 内存对齐

// 内存池对齐分配
#define NGX_POOL_ALIGNMENT       16
#define ngx_align(d, a)     (((d) + (a - 1)) & ~(a - 1))
#define ngx_align_ptr(p, a)                                                   \
    (u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))

// 确保数据结构对齐
p->d.last = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);

9.2 缓存友好设计

// 事件结构紧凑排列,提高缓存命中率
struct ngx_event_s {
    void            *data;           // 8字节
    
    // 位域紧凑存储,减少内存占用
    unsigned         write:1;
    unsigned         accept:1;
    unsigned         instance:1;
    // ... 更多位域
    
    int              available;      // 4字节
    ngx_event_handler_pt  handler;   // 8字节
    // ...
};

9.3 零拷贝支持

// 缓冲区支持多种数据源
struct ngx_buf_s {
    u_char          *pos;            // 内存数据
    u_char          *last;
    off_t            file_pos;       // 文件数据
    off_t            file_last;
    
    unsigned         memory:1;       // 内存缓冲区
    unsigned         in_file:1;      // 文件缓冲区
    unsigned         mmap:1;         // mmap缓冲区
    // ...
};

10. 实战应用示例

10.1 自定义数据结构

// 定义包含队列节点的数据结构
typedef struct {
    ngx_queue_t       queue;         // 队列节点
    ngx_rbtree_node_t rbnode;        // 红黑树节点
    ngx_str_t         key;           // 键
    ngx_str_t         value;         // 值
    time_t            expire;        // 过期时间
} my_cache_node_t;

// 初始化缓存
typedef struct {
    ngx_queue_t       lru_queue;     // LRU队列
    ngx_rbtree_t      rbtree;        // 查找树
    ngx_rbtree_node_t sentinel;      // 哨兵节点
    ngx_pool_t       *pool;          // 内存池
    ngx_uint_t        max_size;      // 最大大小
    ngx_uint_t        current_size;  // 当前大小
} my_cache_t;

// 缓存操作函数
my_cache_t *
my_cache_create(ngx_pool_t *pool, ngx_uint_t max_size)
{
    my_cache_t *cache;
    
    cache = ngx_palloc(pool, sizeof(my_cache_t));
    if (cache == NULL) {
        return NULL;
    }
    
    ngx_queue_init(&cache->lru_queue);
    ngx_rbtree_init(&cache->rbtree, &cache->sentinel,
                    ngx_rbtree_insert_value);
    
    cache->pool = pool;
    cache->max_size = max_size;
    cache->current_size = 0;
    
    return cache;
}

my_cache_node_t *
my_cache_lookup(my_cache_t *cache, ngx_str_t *key)
{
    uint32_t          hash;
    ngx_rbtree_node_t *node, *sentinel;
    my_cache_node_t   *cn;
    
    hash = ngx_crc32_short(key->data, key->len);
    
    node = cache->rbtree.root;
    sentinel = cache->rbtree.sentinel;
    
    while (node != sentinel) {
        if (hash < node->key) {
            node = node->left;
            continue;
        }
        
        if (hash > node->key) {
            node = node->right;
            continue;
        }
        
        /* hash == node->key */
        
        cn = (my_cache_node_t *) node;
        
        if (key->len == cn->key.len
            && ngx_memcmp(key->data, cn->key.data, key->len) == 0)
        {
            // 移到LRU队列头部
            ngx_queue_remove(&cn->queue);
            ngx_queue_insert_head(&cache->lru_queue, &cn->queue);
            
            return cn;
        }
        
        node = (hash < node->key) ? node->left : node->right;
    }
    
    return NULL;
}

10.2 内存池使用最佳实践

// 分层内存池设计
typedef struct {
    ngx_pool_t  *main_pool;      // 主池,生命周期长
    ngx_pool_t  *temp_pool;      // 临时池,频繁重置
    ngx_pool_t  *request_pool;   // 请求池,请求结束时销毁
} my_pools_t;

// 初始化分层池
my_pools_t *
my_pools_create(ngx_log_t *log)
{
    my_pools_t *pools;
    
    pools = ngx_alloc(sizeof(my_pools_t), log);
    if (pools == NULL) {
        return NULL;
    }
    
    pools->main_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, log);
    if (pools->main_pool == NULL) {
        ngx_free(pools);
        return NULL;
    }
    
    pools->temp_pool = ngx_create_pool(4096, log);
    if (pools->temp_pool == NULL) {
        ngx_destroy_pool(pools->main_pool);
        ngx_free(pools);
        return NULL;
    }
    
    pools->request_pool = NULL;  // 按需创建
    
    return pools;
}

// 请求开始时创建请求池
ngx_int_t
my_request_start(my_pools_t *pools)
{
    if (pools->request_pool) {
        ngx_destroy_pool(pools->request_pool);
    }
    
    pools->request_pool = ngx_create_pool(8192, pools->main_pool->log);
    return (pools->request_pool != NULL) ? NGX_OK : NGX_ERROR;
}

// 请求结束时销毁请求池
void
my_request_end(my_pools_t *pools)
{
    if (pools->request_pool) {
        ngx_destroy_pool(pools->request_pool);
        pools->request_pool = NULL;
    }
    
    // 重置临时池
    ngx_reset_pool(pools->temp_pool);
}

11. 总结

Nginx的数据结构设计体现了以下特点:

11.1 设计原则

  • 内存高效: 内存池管理,减少碎片和泄漏
  • 缓存友好: 数据结构紧凑,提高缓存命中率
  • 类型安全: 强类型设计,减少运行时错误
  • 性能优先: 针对高频操作优化数据结构

11.2 核心优势

  • 统一的内存管理: 内存池提供统一的分配和释放机制
  • 高效的容器: 针对不同场景选择最优的数据结构
  • 零拷贝支持: 缓冲区设计支持多种数据源
  • 模块化设计: 清晰的模块和配置结构

11.3 应用价值

  • 为高性能网络服务器提供基础数据结构
  • 统一的编程模型,简化开发复杂度
  • 优秀的性能表现,支撑大规模应用
  • 可扩展的架构,支持自定义数据结构

通过深入理解这些数据结构的设计思想和实现细节,开发者可以更好地利用Nginx的基础设施,开发高性能的网络应用。