NGINX系列之MAIN函数
近期在系统学习Nginx相关源码,针对nginx进程模型、事件处理模型、配置以及扩展开发等诸多⽅⾯希望能够沉淀⼀些东西,故针对上述⽅⾯整理⼀系列博客,既然是源码分析,那就⾸先从main函数开始吧。
核⼼数据结构
全局变量cycle数据结构
ngx_cycle_s变量是nginx中贯穿始终的全局变量,其存储在系统运⾏过程中的所有信息,包括配置⽂件信息、模块信息、客户端连接、读写事件处理函数等信息。其结构如下所⽰:
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; /* unsigned log_use_stderr:1; */
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; /* unsigned modules_used:1; */
ngx_queue_t reusable_connections_queue;
ngx_uint_t reusable_connections_n;
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 lock_file;
ngx_str_t hostname;
};
Main核⼼配置数据结构
//核⼼配置
typedef struct {
ngx_flag_t daemon;
ngx_flag_t master;
ngx_msec_t timer_resolution;
ngx_msec_t shutdown_timeout;
ngx_int_t worker_processes;
ngx_int_t debug_points;
ngx_int_t rlimit_nofile;
off_t rlimit_core;
int priority;
ngx_uint_t cpu_affinity_auto;
ngx_uint_t cpu_affinity_n;
ngx_cpuset_t *cpu_affinity;
char *username;
ngx_uid_t user;
ngx_gid_t group;
ngx_str_t working_directory;
ngx_str_t lock_file;
ngx_str_t pid;
ngx_str_t oldpid;
ngx_array_t env;
char **environment;
ngx_uint_t transparent; /* unsigned transparent:1; */ } ngx_core_conf_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;
};
typedef struct {
ngx_str_t name;
void *(*create_conf)(ngx_cycle_t *cycle);
char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
} ngx_core_module_t;
主函数 main()
⽂件位置:/src/nginx.c
int ngx_cdecl main(int argc, char *const *argv)
{
ngx_buf_t *b;
ngx_log_t *log;
ngx_uint_t i;
ngx_cycle_t *cycle, init_cycle;
ngx_conf_dump_t *cd;
ngx_core_conf_t *ccf;
ngx_debug_init();
nginx 配置文件// 1.获取命令⾏参数
ngx_get_options(argc, argv)
// 2.初始化本地时钟
ngx_time_init();
ngx_pid = ngx_getpid();
ngx_parent = ngx_getppid();
// 3.初始化⽇志
log = ngx_log_init(ngx_prefix);
// 4.初始化全局变量ngx_cycle_t
ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
init_cycle.log = log;
ngx_cycle = &init_cycle;
init_cycle.pool = ngx_create_pool(1024, log);
// 5.保存命令⾏参数到全局变量中
ngx_save_argv(&init_cycle, argc, argv);
// 6.处理命令⾏参数
ngx_process_options(&init_cycle);
// 7.初始化系统相关参数
ngx_os_init(log);
// 8.预初始化模块
ngx_preinit_modules();
/
/ 9.
cycle = ngx_init_cycle(&init_cycle);
ngx_os_status(cycle->log);
ngx_cycle = cycle;
// 9.获取核⼼模块配置参数
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
// 10.创建pid存储⽂件
ngx_create_pidfile(&ccf->pid, cycle->log);
ngx_log_redirect_stderr(cycle);
// 11.单进程模式运⾏
if (ngx_process == NGX_PROCESS_SINGLE) {
ngx_single_process_cycle(cycle);
} else {
// 12.多进程模式运⾏
ngx_master_process_cycle(cycle);
}
return0;
}
预初始化模块ngx_preinit_modules()
⽂件位置 /src/ngx_module.c
主要⼯作:配置各个模块的顺序索引
ngx_int_t ngx_preinit_modules(void)
{
ngx_uint_t i;
//ngx_modules是全局变量,定义在nginx_modules.h⽂件中
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;
}
ngx_preinit_modules()函数主要完成模块到序号初始化,其数组ngx_modules是何时产⽣的呢?
ngx_modules包含所有nginx定义的模块,其初始化是由执⾏configure命令前定义.
新增模块或者减少模块可以在configure命令执⾏前 auto/modules⽂件⾥⾯修改。
ngx_init_cycle
⽂件位置 /src/ngx_module.c
主要⼯作:初始化系统时钟、主机名、模块配置⽂件、各种后续数据结构,形成全局变量cycle
ngx_cycle_t * ngx_init_cycle(ngx_cycle_t *old_cycle)
{
void *rv;
char **senv;
ngx_uint_t i, n;
ngx_log_t *log;
ngx_time_t *tp;
ngx_conf_t conf;
ngx_pool_t *pool;
ngx_cycle_t *cycle, **old;
ngx_shm_zone_t *shm_zone, *oshm_zone;
ngx_list_part_t *part, *opart;
ngx_open_file_t *file;
ngx_listening_t *ls, *nls;
ngx_core_conf_t *ccf, *old_ccf;
ngx_core_module_t *module;
char hostname[NGX_MAXHOSTNAMELEN];
// 1.更新时钟和时区
ngx_timezone_update();
ngx_time_update();
log = old_cycle->log;
pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
pool->log = log;
cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
cycle->pool = pool;
cycle->log = log;
cycle->old_cycle = old_cycle;
/
/ 2.初始化相关数据结构
ngx_array_init(&cycle->paths, pool, n, sizeof(ngx_path_t *);
ngx_memzero(cycle->paths.elts, n * sizeof(ngx_path_t *);
ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t);
ngx_rbtree_init(&cycle->config_dump_rbtree, &cycle->config_dump_sentinel,ngx_str_rbtree_insert_value);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论