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. 灵活性

    • 为动态模块预留空间,支持模块的动态加载和卸载。
    • 允许开发者通过配置文件加载额外的功能模块,增强系统的可扩展性。
相关推荐
序属秋秋秋4 小时前
《Linux系统编程之进程环境》【环境变量】
linux·运维·服务器·c语言·c++·操作系统·系统编程
Altair12315 小时前
nginx的https的搭建
运维·网络·nginx·云计算
云计算练习生5 小时前
linux shell编程实战 10 Git工具详解与运维场景实战
linux·运维·git
虚伪的空想家7 小时前
KVM的ubuntu虚机如何关闭安全启动
linux·安全·ubuntu
t1987512813 小时前
在Ubuntu 22.04系统上安装libimobiledevice
linux·运维·ubuntu
skywalk816313 小时前
linux安装Code Server 以便Comate IDE和CodeBuddy等都可以远程连上来
linux·运维·服务器·vscode·comate
晚风吹人醒.14 小时前
缓存中间件Redis安装及功能演示、企业案例
linux·数据库·redis·ubuntu·缓存·中间件
记得记得就15114 小时前
【Nginx 性能优化与防盗链】
运维·nginx·性能优化
Hard but lovely14 小时前
linux: pthread库的使用和理解
linux