Ubuntu 下 nginx-1.24.0 源码分析 - ngx_preinit_modules 函数

ngx_preinit_modules

声明在 src\core\ngx_module.h

c 复制代码
ngx_int_t ngx_preinit_modules(void);

实现在 src\core\ngx_module.c

c 复制代码
ngx_int_t
ngx_preinit_modules(void)
{
    ngx_uint_t  i;

    for (i = 0; ngx_modules[i]; i++) {
        ngx_modules[i]->index = i;
        ngx_modules[i]->name = ngx_module_names[i];
    }

    ngx_modules_n = i;
    ngx_max_module = ngx_modules_n + NGX_MAX_DYNAMIC_MODULES;

    return NGX_OK;
}

在 Nginx 中,模块(module)是其核心架构的基础。

Nginx 的功能几乎完全由模块实现,包括核心模块、HTTP 模块、事件模块等。

为了管理这些模块,Nginx 在启动时会对所有静态模块进行初始化,并为动态模块预留空间。

ngx_preinit_modules 函数的主要作用是对静态模块进行预初始化,

设置每个模块的基本信息(如索引值和名称),

并计算模块的最大数量。

这是 Nginx 启动过程中非常重要的一步。


函数定义与参数
c 复制代码
ngx_int_t ngx_preinit_modules(void)
  • 返回值ngx_int_t 类型,表示操作结果。成功返回 NGX_OK,失败返回 NGX_ERROR
  • 参数:无参数。

代码分析
1. 遍历 ngx_modules 数组
c 复制代码
ngx_uint_t  i;
for (i = 0; ngx_modules[i]; i++) {
    ngx_modules[i]->index = i;
    ngx_modules[i]->name = ngx_module_names[i];
}
  • 作用
    • 遍历全局数组 ngx_modules,对每个模块进行初始化。
    • 设置模块的索引值(index)和名称(name)。
  • 逻辑
    • ngx_modules 是一个全局数组,包含了所有的静态模块。
    • ngx_modules[i] 是指向第 i 个模块的指针。
    • ngx_modules[i]->index = i:为模块分配一个唯一的索引值。
    • ngx_modules[i]->name = ngx_module_names[i]:将模块名称从 ngx_module_names 数组中赋值给模块。
  • 意图
    • 索引值用于标识模块,方便后续查找和管理。
    • 名称用于调试和日志记录,便于开发者定位问题。

ngx_modules、ngx_modules

定义在 objs\ngx_modules.c

c 复制代码
#include <ngx_config.h>
#include <ngx_core.h>



extern ngx_module_t  ngx_core_module;
extern ngx_module_t  ngx_errlog_module;
extern ngx_module_t  ngx_conf_module;
extern ngx_module_t  ngx_openssl_module;
extern ngx_module_t  ngx_regex_module;
extern ngx_module_t  ngx_events_module;
extern ngx_module_t  ngx_event_core_module;
extern ngx_module_t  ngx_epoll_module;
extern ngx_module_t  ngx_http_module;
extern ngx_module_t  ngx_http_core_module;
extern ngx_module_t  ngx_http_log_module;
extern ngx_module_t  ngx_http_upstream_module;
extern ngx_module_t  ngx_http_v2_module;
extern ngx_module_t  ngx_http_static_module;
extern ngx_module_t  ngx_http_gzip_static_module;
extern ngx_module_t  ngx_http_autoindex_module;
extern ngx_module_t  ngx_http_index_module;
extern ngx_module_t  ngx_http_mirror_module;
extern ngx_module_t  ngx_http_try_files_module;
extern ngx_module_t  ngx_http_auth_basic_module;
extern ngx_module_t  ngx_http_access_module;
extern ngx_module_t  ngx_http_limit_conn_module;
extern ngx_module_t  ngx_http_limit_req_module;
extern ngx_module_t  ngx_http_geo_module;
extern ngx_module_t  ngx_http_map_module;
extern ngx_module_t  ngx_http_split_clients_module;
extern ngx_module_t  ngx_http_referer_module;
extern ngx_module_t  ngx_http_rewrite_module;
extern ngx_module_t  ngx_http_ssl_module;
extern ngx_module_t  ngx_http_proxy_module;
extern ngx_module_t  ngx_http_fastcgi_module;
extern ngx_module_t  ngx_http_uwsgi_module;
extern ngx_module_t  ngx_http_scgi_module;
extern ngx_module_t  ngx_http_grpc_module;
extern ngx_module_t  ngx_http_memcached_module;
extern ngx_module_t  ngx_http_empty_gif_module;
extern ngx_module_t  ngx_http_browser_module;
extern ngx_module_t  ngx_http_upstream_hash_module;
extern ngx_module_t  ngx_http_upstream_ip_hash_module;
extern ngx_module_t  ngx_http_upstream_least_conn_module;
extern ngx_module_t  ngx_http_upstream_random_module;
extern ngx_module_t  ngx_http_upstream_keepalive_module;
extern ngx_module_t  ngx_http_upstream_zone_module;
extern ngx_module_t  ngx_http_write_filter_module;
extern ngx_module_t  ngx_http_header_filter_module;
extern ngx_module_t  ngx_http_chunked_filter_module;
extern ngx_module_t  ngx_http_v2_filter_module;
extern ngx_module_t  ngx_http_range_header_filter_module;
extern ngx_module_t  ngx_http_gzip_filter_module;
extern ngx_module_t  ngx_http_postpone_filter_module;
extern ngx_module_t  ngx_http_ssi_filter_module;
extern ngx_module_t  ngx_http_charset_filter_module;
extern ngx_module_t  ngx_http_userid_filter_module;
extern ngx_module_t  ngx_http_headers_filter_module;
extern ngx_module_t  ngx_http_copy_filter_module;
extern ngx_module_t  ngx_http_range_body_filter_module;
extern ngx_module_t  ngx_http_not_modified_filter_module;
extern ngx_module_t  ngx_stream_module;
extern ngx_module_t  ngx_stream_core_module;
extern ngx_module_t  ngx_stream_log_module;
extern ngx_module_t  ngx_stream_proxy_module;
extern ngx_module_t  ngx_stream_upstream_module;
extern ngx_module_t  ngx_stream_write_filter_module;
extern ngx_module_t  ngx_stream_ssl_module;
extern ngx_module_t  ngx_stream_limit_conn_module;
extern ngx_module_t  ngx_stream_access_module;
extern ngx_module_t  ngx_stream_geo_module;
extern ngx_module_t  ngx_stream_map_module;
extern ngx_module_t  ngx_stream_split_clients_module;
extern ngx_module_t  ngx_stream_return_module;
extern ngx_module_t  ngx_stream_set_module;
extern ngx_module_t  ngx_stream_upstream_hash_module;
extern ngx_module_t  ngx_stream_upstream_least_conn_module;
extern ngx_module_t  ngx_stream_upstream_random_module;
extern ngx_module_t  ngx_stream_upstream_zone_module;

ngx_module_t *ngx_modules[] = {
    &ngx_core_module,
    &ngx_errlog_module,
    &ngx_conf_module,
    &ngx_openssl_module,
    &ngx_regex_module,
    &ngx_events_module,
    &ngx_event_core_module,
    &ngx_epoll_module,
    &ngx_http_module,
    &ngx_http_core_module,
    &ngx_http_log_module,
    &ngx_http_upstream_module,
    &ngx_http_v2_module,
    &ngx_http_static_module,
    &ngx_http_gzip_static_module,
    &ngx_http_autoindex_module,
    &ngx_http_index_module,
    &ngx_http_mirror_module,
    &ngx_http_try_files_module,
    &ngx_http_auth_basic_module,
    &ngx_http_access_module,
    &ngx_http_limit_conn_module,
    &ngx_http_limit_req_module,
    &ngx_http_geo_module,
    &ngx_http_map_module,
    &ngx_http_split_clients_module,
    &ngx_http_referer_module,
    &ngx_http_rewrite_module,
    &ngx_http_ssl_module,
    &ngx_http_proxy_module,
    &ngx_http_fastcgi_module,
    &ngx_http_uwsgi_module,
    &ngx_http_scgi_module,
    &ngx_http_grpc_module,
    &ngx_http_memcached_module,
    &ngx_http_empty_gif_module,
    &ngx_http_browser_module,
    &ngx_http_upstream_hash_module,
    &ngx_http_upstream_ip_hash_module,
    &ngx_http_upstream_least_conn_module,
    &ngx_http_upstream_random_module,
    &ngx_http_upstream_keepalive_module,
    &ngx_http_upstream_zone_module,
    &ngx_http_write_filter_module,
    &ngx_http_header_filter_module,
    &ngx_http_chunked_filter_module,
    &ngx_http_v2_filter_module,
    &ngx_http_range_header_filter_module,
    &ngx_http_gzip_filter_module,
    &ngx_http_postpone_filter_module,
    &ngx_http_ssi_filter_module,
    &ngx_http_charset_filter_module,
    &ngx_http_userid_filter_module,
    &ngx_http_headers_filter_module,
    &ngx_http_copy_filter_module,
    &ngx_http_range_body_filter_module,
    &ngx_http_not_modified_filter_module,
    &ngx_stream_module,
    &ngx_stream_core_module,
    &ngx_stream_log_module,
    &ngx_stream_proxy_module,
    &ngx_stream_upstream_module,
    &ngx_stream_write_filter_module,
    &ngx_stream_ssl_module,
    &ngx_stream_limit_conn_module,
    &ngx_stream_access_module,
    &ngx_stream_geo_module,
    &ngx_stream_map_module,
    &ngx_stream_split_clients_module,
    &ngx_stream_return_module,
    &ngx_stream_set_module,
    &ngx_stream_upstream_hash_module,
    &ngx_stream_upstream_least_conn_module,
    &ngx_stream_upstream_random_module,
    &ngx_stream_upstream_zone_module,
    NULL
};

char *ngx_module_names[] = {
    "ngx_core_module",
    "ngx_errlog_module",
    "ngx_conf_module",
    "ngx_openssl_module",
    "ngx_regex_module",
    "ngx_events_module",
    "ngx_event_core_module",
    "ngx_epoll_module",
    "ngx_http_module",
    "ngx_http_core_module",
    "ngx_http_log_module",
    "ngx_http_upstream_module",
    "ngx_http_v2_module",
    "ngx_http_static_module",
    "ngx_http_gzip_static_module",
    "ngx_http_autoindex_module",
    "ngx_http_index_module",
    "ngx_http_mirror_module",
    "ngx_http_try_files_module",
    "ngx_http_auth_basic_module",
    "ngx_http_access_module",
    "ngx_http_limit_conn_module",
    "ngx_http_limit_req_module",
    "ngx_http_geo_module",
    "ngx_http_map_module",
    "ngx_http_split_clients_module",
    "ngx_http_referer_module",
    "ngx_http_rewrite_module",
    "ngx_http_ssl_module",
    "ngx_http_proxy_module",
    "ngx_http_fastcgi_module",
    "ngx_http_uwsgi_module",
    "ngx_http_scgi_module",
    "ngx_http_grpc_module",
    "ngx_http_memcached_module",
    "ngx_http_empty_gif_module",
    "ngx_http_browser_module",
    "ngx_http_upstream_hash_module",
    "ngx_http_upstream_ip_hash_module",
    "ngx_http_upstream_least_conn_module",
    "ngx_http_upstream_random_module",
    "ngx_http_upstream_keepalive_module",
    "ngx_http_upstream_zone_module",
    "ngx_http_write_filter_module",
    "ngx_http_header_filter_module",
    "ngx_http_chunked_filter_module",
    "ngx_http_v2_filter_module",
    "ngx_http_range_header_filter_module",
    "ngx_http_gzip_filter_module",
    "ngx_http_postpone_filter_module",
    "ngx_http_ssi_filter_module",
    "ngx_http_charset_filter_module",
    "ngx_http_userid_filter_module",
    "ngx_http_headers_filter_module",
    "ngx_http_copy_filter_module",
    "ngx_http_range_body_filter_module",
    "ngx_http_not_modified_filter_module",
    "ngx_stream_module",
    "ngx_stream_core_module",
    "ngx_stream_log_module",
    "ngx_stream_proxy_module",
    "ngx_stream_upstream_module",
    "ngx_stream_write_filter_module",
    "ngx_stream_ssl_module",
    "ngx_stream_limit_conn_module",
    "ngx_stream_access_module",
    "ngx_stream_geo_module",
    "ngx_stream_map_module",
    "ngx_stream_split_clients_module",
    "ngx_stream_return_module",
    "ngx_stream_set_module",
    "ngx_stream_upstream_hash_module",
    "ngx_stream_upstream_least_conn_module",
    "ngx_stream_upstream_random_module",
    "ngx_stream_upstream_zone_module",
    NULL
};

ngx_module_t

定义在 src/core/ngx_core.h

c 复制代码
typedef struct ngx_module_s          ngx_module_t;

ngx_module_s

定义在 src/core/ngx_module.h

c 复制代码
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;
};

2. 记录静态模块的数量
c 复制代码
ngx_modules_n = i;
  • 作用:记录静态模块的数量。
  • 逻辑
    • i 是遍历 ngx_modules 数组时的计数器,最终值即为静态模块的数量。
    • 将其赋值给全局变量 ngx_modules_n
  • 意图
    • 保存静态模块的数量,供后续使用(如分配内存或计算最大模块数)。

3. 计算最大模块数量
c 复制代码
ngx_max_module = ngx_modules_n + NGX_MAX_DYNAMIC_MODULES;
  • 作用:计算系统支持的最大模块数量。
  • 逻辑
    • ngx_max_module 是一个全局变量,表示系统允许的最大模块数量。
    • ngx_modules_n 是静态模块的数量。
    • NGX_MAX_DYNAMIC_MODULES 是一个常量,表示系统为动态模块预留的空间,默认值为 128。
    • 最大模块数量等于静态模块数量加上动态模块预留空间。
  • 意图
    • 为动态模块预留足够的空间,确保系统可以加载额外的模块。
    • 防止模块数量超出限制,导致内存分配失败或其他问题。

4. 返回成功状态
c 复制代码
return NGX_OK;
  • 作用:返回成功状态。
  • 逻辑
    • 如果所有操作都顺利完成,函数返回 NGX_OK
  • 意图
    • 告知调用者初始化过程成功完成。

总结

我们可以看到 ngx_preinit_modules 函数的设计具有以下特点:

  1. 模块化

    • 每个模块都有唯一的索引值和名称,便于管理和调试。
    • 静态模块和动态模块分开处理,保持代码清晰且易于扩展。
  2. 灵活性

    • 为动态模块预留空间,支持模块的动态加载和卸载。
    • 允许开发者通过配置文件加载额外的功能模块,增强系统的可扩展性。
相关推荐
Koma_zhe1 小时前
【搭建SigNoz性能监控平台】在Ubuntu上快速搭建高效的SigNoz性能监控平台与远程使用技巧
linux·运维·ubuntu
thinkerCoder1 小时前
ubuntu 20.04系统离线安装nfs
ubuntu·k8s·共享文件·k8
xxxx1234451 小时前
Ubuntu中出现对control.tar.zst未知压缩
linux·运维·ubuntu
漫天转悠1 小时前
VMware17下Ubuntu22.04设置本地共享文件夹
ubuntu
淳杰1 小时前
ubuntu部署小笔记-采坑
linux·笔记·ubuntu
茂茂在长安1 小时前
Linux 命令大全完整版(12)
linux·运维·服务器·数据库·运维开发
技匠而已1 小时前
ubuntu安装docker & docker/DockerHub 国内镜像源/加速列表【持续更新】
linux·ubuntu·docker
WIFI_BT_DEV2 小时前
Linux设备驱动开发-中断
linux·c语言·arm开发·驱动开发·嵌入式硬件·硬件架构·gnu
2401_878961722 小时前
九、k8s:ingress
linux·容器·kubernetes
小志biubiu2 小时前
Linux版本控制器Git【Ubuntu系统】
linux·运维·服务器·git·学习·ubuntu