下载的代码版本是nginx-1.18.0
- 从nginx-1.18.0/src/core/nginx.c的main函数调用次序开始
ngx_debug_init
ngx_debug_init();
if (ngx_strerror_init() != NGX_OK) {
return 1;
}
if (ngx_get_options(argc, argv) != NGX_OK) {
return 1;
}
ngx_debug_init是初始化debug用的,nginx中的debug,主要是对内存池分配管理方面的debug,因为作为一个应用程序,最容易出现bug的地方也是内存管理这块。在Linux版本中,这个函数只是一个空定义src/os/unix/ngx_linux_config.h
,还有两个版本,src/os/unix/ngx_darwin_init.c
和src/os/unix/ngx_freebsd_init.c
中有定义。
ngx_strerror_init把error值从0到135转成字符串,保存在nginx的ngx_sys_errlist中,供后续使用。
ngx_get_options处理命令行参数,如果是-h选项,打印help输出。
ngx_show_version_info
if (ngx_show_version) {
ngx_show_version_info();
if (!ngx_test_config) {
return 0;
}
}
输出版本信息,help信息也是在ngx_show_version_info里面通过ngx_show_help变量输出的。
ngx_time_init
初始化nginx的时间相关变量
volatile ngx_msec_t ngx_current_msec;
volatile ngx_time_t *ngx_cached_time;
volatile ngx_str_t ngx_cached_err_log_time;
volatile ngx_str_t ngx_cached_http_time;
volatile ngx_str_t ngx_cached_http_log_time;
volatile ngx_str_t ngx_cached_http_log_iso8601;
volatile ngx_str_t ngx_cached_syslog_time;
ngx_regex_init
如果定义了NGX_PCRE,ngx_regex_init会对正则表达式库PCRE进行初始化。
PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括 perl 兼容的正则表达式库。
\#if (NGX_PCRE)
ngx_regex_init();
\#endif
ngx_log_init
初始化ngx_pid和ngx_parent
初始化nginx log子系统
ngx_pid = ngx_getpid();
ngx_parent = ngx_getppid();
log = ngx_log_init(ngx_prefix);
if (log == NULL) {
return 1;
}
log文件记录在NGX_PREFIX/logs/error.log文件中
这些文件在configure执行后自动生成ngx_auto_config.h
ngx_auto_config.h:#define NGX_PREFIX "/usr/local/nginx/"
ngx_auto_config.h:#define NGX_CONF_PREFIX "conf/"
ngx_auto_config.h:#define NGX_SBIN_PATH "sbin/nginx"
ngx_auto_config.h:#define NGX_CONF_PATH "conf/nginx.conf"
ngx_auto_config.h:#define NGX_PID_PATH "logs/nginx.pid"
ngx_auto_config.h:#define NGX_LOCK_PATH "logs/nginx.lock"
ngx_auto_config.h:#define NGX_ERROR_LOG_PATH "logs/error.log"
ngx_auto_config.h:#define NGX_HTTP_LOG_PATH "logs/access.log"
ngx_ssl_init
#if (NGX_OPENSSL)
ngx_ssl_init(log);
#endif
在ngx_ssl_init中有openssl版本号做分支的代码,版本号大于等于0x10100003L的走的是OPENSSL_init_ssl的接口,小于这个走的是OPENSSL_config,SSL_library_init接口,后面需要再具体深入看一下。
ngx_memzero & ngx_create_pool
ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
init_cycle.log = log;
ngx_cycle = &init_cycle;
init_cycle.pool = ngx_create_pool(1024, log);
if (init_cycle.pool == NULL) {
return 1;
}
全局变量init_cycle清零,并创建改变量的内存池pool,这个需要再结合cycle_init深入看一下。
ngx_save_argv
if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
return 1;
}
保存命令行参数至全局变量ngx_os_argv、ngx_argc、ngx_argv
ngx_process_options
初始化全局变量init_cycle中的成员:prefix、conf_prefix、conf_file、conf_param 等字段
ngx_os_init
初始化系统相关变量,如:内存页面大小ngx_pagesize、最大连接数ngx_max_sockets等,这里面sysconf,sysinfo的系统调用用的比较多。比如获取系统pagesize,cpu核数等就是通过sysconf获取的。
ngx_crc32_table_init
初始化 CRC 表(循环冗余校验表)
ngx_add_inherited_sockets
通过环境变量NGINX完成socket的继承,将其保存在全局变量init_cycle的listening数组中。
ngx_preinit_modules
初始化每个模块module的index,并计算ngx_max_module
ngx_modules定义了所有的nginx module,在configure阶段,编译不同的参数就需要通过configure参数指定不同的module。
ngx_module_t *ngx_modules[] = {
&ngx_core_module,
&ngx_errlog_module,
&ngx_conf_module,
&ngx_rtmp_module,
&ngx_rtmp_core_module,
&ngx_rtmp_cmd_module,
&ngx_rtmp_codec_module,
&ngx_rtmp_access_module,
&ngx_rtmp_record_module,
&ngx_rtmp_live_module,
&ngx_rtmp_play_module,
&ngx_rtmp_flv_module,
&ngx_rtmp_mp4_module,
&ngx_rtmp_netcall_module,
&ngx_rtmp_relay_module,
&ngx_rtmp_exec_module,
&ngx_rtmp_auto_push_module,
&ngx_rtmp_auto_push_index_module,
&ngx_rtmp_notify_module,
&ngx_rtmp_log_module,
&ngx_rtmp_limit_module,
&ngx_rtmp_hls_module,
&ngx_rtmp_dash_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_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_memcached_module,
&ngx_http_empty_gif_module,
&ngx_http_browser_module,
&ngx_http_flv_module,
&ngx_http_mp4_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_rtmp_stat_module,
&ngx_rtmp_control_module,
&ngx_http_write_filter_module,
&ngx_http_header_filter_module,
&ngx_http_chunked_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,
NULL
};
ngx_init_cycle
初始化全局变量init_cycle,这个是最重要的部分,需要分解来看。
- 更新时区与时间
- 创建内存池
- 分配 ngx_cycle_t 结构体内存,创建该结构的变量 cycle 并初始化
- 遍历所有 core模块,并调用该模块的 create_conf() 函数
- 配置文件解析
- 遍历所有core模块,并调用core模块的init_conf()函数
- 遍历 open_files 链表中的每一个文件并打开
- 创建新的共享内存并初始化
- 遍历 listening 数组并打开所有侦听
- 提交新的 cycle 配置,并调用所有模块的init_module
- 关闭或删除不被使用的在 old_cycle 中的资源
- 释放多余的共享内存
- 关闭多余的侦听 sockets
- 关闭多余的打开文件
ngx_signal_process
ngx_signal_process 函数从配置文件中获取 nginx 进程 pid 文件路径,然后读取文件里的 pid ,最后调用 ngx_os_signal_process 函数,ngx_os_signal_process 函数是与操作系统相关的函数,它将 ngx_signal 的值与全局数组 signals 中各项比较,如果名字相同,就调用 kill 向正在运行的 nginx master 进程发送特定的信号。
signals 数组的定义如下:
ngx_signal_t signals[] = {
{ ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
"SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
"reload",
ngx_signal_handler },
{ ngx_signal_value(NGX_REOPEN_SIGNAL),
"SIG" ngx_value(NGX_REOPEN_SIGNAL),
"reopen",
ngx_signal_handler },
{ ngx_signal_value(NGX_NOACCEPT_SIGNAL),
"SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
"",
ngx_signal_handler },
{ ngx_signal_value(NGX_TERMINATE_SIGNAL),
"SIG" ngx_value(NGX_TERMINATE_SIGNAL),
"stop",
ngx_signal_handler },
{ ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
"SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
"quit",
ngx_signal_handler },
{ ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
"SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
"",
ngx_signal_handler },
{ SIGALRM, "SIGALRM", "", ngx_signal_handler },
{ SIGINT, "SIGINT", "", ngx_signal_handler },
{ SIGIO, "SIGIO", "", ngx_signal_handler },
{ SIGCHLD, "SIGCHLD", "", ngx_signal_handler },
{ SIGSYS, "SIGSYS, SIG_IGN", "", NULL },
{ SIGPIPE, "SIGPIPE, SIG_IGN", "", NULL },
{ 0, NULL, "", NULL }
};