NGINX源代码自我总结(一)
查看源代码入门
这是一篇关于NGINX的MAIN()函数入门说明文章,相比其他这篇十分枯燥,其实写的时候更是无聊,不过学了这么长时间的WEB开发,连NGINX源代码都没有读下来,总是觉得有些缺憾,希望这一次可以弥补一下。
一、下载NGINX
- 下载地址:http://nginx.org/en/download.html
- tar -zxvf *.tar.gz && ./configure && make && sudo make install
- 查看NGINX目录有如下文件夹:
auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src
二、使用gdb跟踪查找入口文件
很多朋友看见NGINX目录有很多的内容,就会头疼,不知道从哪里开始,下面就分享一个方法。进入objs目录,会发现nginx是可执行文件,使用gdb跟踪一下(如果没有gdb,执行命令:sudo yum install yum安装即可),依次执行如下命令:
2.1 gdb nginx
进入nginx程序
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-.el6_4.)
Copyright (C) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/soft/ngx_openresty-1.4.1.1/build/nginx-1.4./objs/nginx...done.
2.2 l main
目的是查看main函数
(gdb) l main
static char **ngx_os_environ; int ngx_cdecl
main(int argc, char *const *argv)
{
ngx_int_t i;
ngx_log_t *log;
ngx_cycle_t *cycle, init_cycle;
ngx_core_conf_t *ccf;
2.3 i li main
查看main()函数的位置
(gdb) i li main
Line of "src/core/nginx.c" starts at address 0x4168cb <main> and ends at 0x4168e1 <main+>.
如上就知道了入口程序文件是:src/core/nginx.c
三、main()函数
int ngx_cdecl
main(int argc, char *const *argv)
{
ngx_int_t i;
ngx_log_t *log;
ngx_cycle_t *cycle, init_cycle;
ngx_core_conf_t *ccf;
//上面是四个堆栈的常量,没啥别的意思。nginx的结构都是_t结束的。
ngx_debug_init();//nginx的函数都是ngx_开头的。下面有解释 if (ngx_strerror_init() != NGX_OK) {
return ;//如果启动失败
} if (ngx_get_options(argc, argv) != NGX_OK) {
return ;//检测命令行参数异常
} if (ngx_show_version) {//ngx_show_version是一个全局变量,可以在gdb里面查看(p ngx_show_version或者i var ngx_show_version)
ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED); if (ngx_show_help) {//自我帮助信息,执行:"nginx -?"时候输出的信息
ngx_write_stderr(
"Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
"[-p prefix] [-g directives]" NGX_LINEFEED
NGX_LINEFEED
"Options:" NGX_LINEFEED
" -?,-h : this help" NGX_LINEFEED
" -v : show version and exit" NGX_LINEFEED
" -V : show version and configure options then exit"
NGX_LINEFEED
" -t : test configuration and exit" NGX_LINEFEED
" -q : suppress non-error messages "
"during configuration testing" NGX_LINEFEED
" -s signal : send signal to a master process: "
"stop, quit, reopen, reload" NGX_LINEFEED
#ifdef NGX_PREFIX
" -p prefix : set prefix path (default: "
NGX_PREFIX ")" NGX_LINEFEED
#else
" -p prefix : set prefix path (default: NONE)" NGX_LINEFEED
#endif
" -c filename : set configuration file (default: "
NGX_CONF_PATH ")" NGX_LINEFEED
" -g directives : set global directives out of configuration "
"file" NGX_LINEFEED NGX_LINEFEED
);
} if (ngx_show_configure) {
ngx_write_stderr(
#ifdef NGX_COMPILER
"built by " NGX_COMPILER NGX_LINEFEED
#endif
#if (NGX_SSL)
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
"TLS SNI support enabled" NGX_LINEFEED
#else
"TLS SNI support disabled" NGX_LINEFEED
#endif
#endif
"configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
} if (!ngx_test_config) {
return ;
}
} /* TODO */ ngx_max_sockets = -; ngx_time_init();//时间初始化 #if (NGX_PCRE)
ngx_regex_init();//宏开关
#endif ngx_pid = ngx_getpid(); log = ngx_log_init(ngx_prefix);//日志初始化
if (log == NULL) {
return ;
} /* STUB */
#if (NGX_OPENSSL)
ngx_ssl_init(log);//ssh初始化
#endif /*
* init_cycle->log is required for signal handlers and
* ngx_process_options()
*/ ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));//init_cycle清零
init_cycle.log = log;
ngx_cycle = &init_cycle; init_cycle.pool = ngx_create_pool(, log);//建立内存池
if (init_cycle.pool == NULL) {
return ;
} if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
return ;
} if (ngx_process_options(&init_cycle) != NGX_OK) {
return ;
} if (ngx_os_init(log) != NGX_OK) {
return ;
} /*
* ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
*/ if (ngx_crc32_table_init() != NGX_OK) {
return ;//crc算法
} if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
return ;
} ngx_max_module = ;
for (i = ; ngx_modules[i]; i++) { //查看一共多少模块
ngx_modules[i]->index = ngx_max_module++;
} cycle = ngx_init_cycle(&init_cycle);//初始化生命周期,下面有讲
if (cycle == NULL) {
if (ngx_test_config) {
ngx_log_stderr(, "configuration file %s test failed",
init_cycle.conf_file.data);
} return ;
} if (ngx_test_config) {
if (!ngx_quiet_mode) {
ngx_log_stderr(, "configuration file %s test is successful",
cycle->conf_file.data);
} return ;
} if (ngx_signal) {
return ngx_signal_process(cycle, ngx_signal);
} ngx_os_status(cycle->log); ngx_cycle = cycle; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
ngx_process = NGX_PROCESS_MASTER;
} #if !(NGX_WIN32) if (ngx_init_signals(cycle->log) != NGX_OK) {
return ;
} if (!ngx_inherited && ccf->daemon) {
if (ngx_daemon(cycle->log) != NGX_OK) {
return ;
} ngx_daemonized = ;
} if (ngx_inherited) {
ngx_daemonized = ;
} #endif if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
return ;
} if (cycle->log->file->fd != ngx_stderr) { if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
ngx_set_stderr_n " failed");
return ;
}
} if (log->file->fd != ngx_stderr) {
if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
ngx_close_file_n " built-in log failed");
}
} ngx_use_stderr = ; if (ngx_process == NGX_PROCESS_SINGLE) {
ngx_single_process_cycle(cycle); } else {
ngx_master_process_cycle(cycle);
} return ;
}
无疑,里面的中文内容肯定是我写的注释。
3.1 ngx_debug_init
使用gdb执行:"i li ngx_debug_init"
(gdb) i li ngx_debug_init
Function "ngx_debug_init" not defined.
(gdb)
没有找到,这个时候只能在文件里面搜索
@~/soft/ngx_openresty-1.4.1.1/build/nginx-1.4./src $ grep -r ngx_debug_init *
core/nginx.c: ngx_debug_init();
os/unix/ngx_freebsd_init.c:ngx_debug_init()
os/unix/ngx_solaris_config.h:#define ngx_debug_init()
os/unix/ngx_linux_config.h:#define ngx_debug_init()
os/unix/ngx_darwin_init.c:ngx_debug_init()
os/unix/ngx_freebsd.h:void ngx_debug_init(void);
os/unix/ngx_posix_config.h:#define ngx_debug_init()
os/unix/ngx_darwin.h:void ngx_debug_init(void);
可见这是一个操作系统相关的内容,先初始化一下。但是什么都没做,所以gdb搜索不到。
3.2 ngx_strerror_init
(gdb) i li ngx_strerror_init
Line of "src/os/unix/ngx_errno.c" starts at address 0x42d8c9 <ngx_strerror_init> and ends at 0x42d8d7 <ngx_strerror_init+>.
然后打开文件ngx_errno.c文件:
ngx_int_t
ngx_strerror_init(void)
{
char *msg;
u_char *p;
size_t len;
ngx_err_t err;
//定义四个堆栈变量
/*
* ngx_strerror() is not ready to work at this stage, therefore,
* malloc() is used and possible errors are logged using strerror().
*/ len = NGX_SYS_NERR * sizeof(ngx_str_t);
//计算长度,注意NGX_SYS_NERR不是在src里面的,而是编译的时候根据操作系统的不同而生成的不内容,这里是在objs/ngx_auto_config.h里面,定义为:135。
ngx_sys_errlist = malloc(len);//申请空间
if (ngx_sys_errlist == NULL) {
goto failed;
} for (err = ; err < NGX_SYS_NERR; err++) {
msg = strerror(err);//如果不是以ngx_开头的,都是系统函数或者其他的库函数。这里是建立一个字符串描述这个错误号
len = ngx_strlen(msg); p = malloc(len);
if (p == NULL) {
goto failed;
} ngx_memcpy(p, msg, len);//系统的错误信息拷贝到自己的空间。
ngx_sys_errlist[err].len = len;
ngx_sys_errlist[err].data = p;
} return NGX_OK; failed: err = errno;
ngx_log_stderr(, "malloc(%uz) failed (%d: %s)", len, err, strerror(err)); return NGX_ERROR;
}
作用是将全局的错误信息复制到一个数组里面,暂时不知道是为什么
3.3 ngx_init_cycle
初始化生命周期。core/ngx_cycle.c,这个函数相当的长。
ngx_cycle_t *
ngx_init_cycle(ngx_cycle_t *old_cycle)
{
void *rv;
char **senv, **env;
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]; ngx_timezone_update(); /* force localtime update with a new timezone */ tp = ngx_timeofday();
tp->sec = ; ngx_time_update(); log = old_cycle->log; pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
if (pool == NULL) {
return NULL;
}
pool->log = log; cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
if (cycle == NULL) {
ngx_destroy_pool(pool);
return NULL;
} cycle->pool = pool;
cycle->log = log;
cycle->new_log.log_level = NGX_LOG_ERR;
cycle->old_cycle = old_cycle; cycle->conf_prefix.len = old_cycle->conf_prefix.len;
cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);
if (cycle->conf_prefix.data == NULL) {
ngx_destroy_pool(pool);
return NULL;
} cycle->prefix.len = old_cycle->prefix.len;
cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix);
if (cycle->prefix.data == NULL) {
ngx_destroy_pool(pool);
return NULL;
} cycle->conf_file.len = old_cycle->conf_file.len;
cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + );
if (cycle->conf_file.data == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data,
old_cycle->conf_file.len + ); cycle->conf_param.len = old_cycle->conf_param.len;
cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param);
if (cycle->conf_param.data == NULL) {
ngx_destroy_pool(pool);
return NULL;
} n = old_cycle->paths.nelts ? old_cycle->paths.nelts : ; cycle->paths.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
if (cycle->paths.elts == NULL) {
ngx_destroy_pool(pool);
return NULL;
} cycle->paths.nelts = ;
cycle->paths.size = sizeof(ngx_path_t *);
cycle->paths.nalloc = n;
cycle->paths.pool = pool; if (old_cycle->open_files.part.nelts) {
n = old_cycle->open_files.part.nelts;
for (part = old_cycle->open_files.part.next; part; part = part->next) {
n += part->nelts;
} } else {
n = ;
} if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
!= NGX_OK)
{
ngx_destroy_pool(pool);
return NULL;
} if (old_cycle->shared_memory.part.nelts) {
n = old_cycle->shared_memory.part.nelts;
for (part = old_cycle->shared_memory.part.next; part; part = part->next)
{
n += part->nelts;
} } else {
n = ;
} if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
!= NGX_OK)
{
ngx_destroy_pool(pool);
return NULL;
} n = old_cycle->listening.nelts ? old_cycle->listening.nelts : ; cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t));
if (cycle->listening.elts == NULL) {
ngx_destroy_pool(pool);
return NULL;
} cycle->listening.nelts = ;
cycle->listening.size = sizeof(ngx_listening_t);
cycle->listening.nalloc = n;
cycle->listening.pool = pool; ngx_queue_init(&cycle->reusable_connections_queue); cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
if (cycle->conf_ctx == NULL) {
ngx_destroy_pool(pool);
return NULL;
} if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed");
ngx_destroy_pool(pool);
return NULL;
} /* on Linux gethostname() silently truncates name that does not fit */ hostname[NGX_MAXHOSTNAMELEN - ] = '\0';
cycle->hostname.len = ngx_strlen(hostname); cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len);
if (cycle->hostname.data == NULL) {
ngx_destroy_pool(pool);
return NULL;
} ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len); for (i = ; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_CORE_MODULE) {
continue;
} module = ngx_modules[i]->ctx; if (module->create_conf) {
rv = module->create_conf(cycle);
if (rv == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
cycle->conf_ctx[ngx_modules[i]->index] = rv;
}
} senv = environ; ngx_memzero(&conf, sizeof(ngx_conf_t));
/* STUB: init array ? */
conf.args = ngx_array_create(pool, , sizeof(ngx_str_t));
if (conf.args == NULL) {
ngx_destroy_pool(pool);
return NULL;
} conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
if (conf.temp_pool == NULL) {
ngx_destroy_pool(pool);
return NULL;
} conf.ctx = cycle->conf_ctx;
conf.cycle = cycle;
conf.pool = pool;
conf.log = log;
conf.module_type = NGX_CORE_MODULE;
conf.cmd_type = NGX_MAIN_CONF; #if 0
log->log_level = NGX_LOG_DEBUG_ALL;
#endif if (ngx_conf_param(&conf) != NGX_CONF_OK) {//解析配置文件,各个模块读取自己的参数
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
} if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
//cycle->conf,指向一块内存,多级指针数组,共44个模块。第0个是核心模块的数据结构,ngx_core_module,如后面3.5所示;第3个是一个指向指针的指针,ngx_events_module。
//第六个指向的ngx的http模块,ngx_http_core数据结构,如3.6所示
if (ngx_test_config && !ngx_quiet_mode) {
ngx_log_stderr(, "the configuration file %s syntax is ok", cycle->conf_file.data);
} for (i = ; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_CORE_MODULE) {
continue;
} module = ngx_modules[i]->ctx; if (module->init_conf) {
if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])
== NGX_CONF_ERROR)
{
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
}
} if (ngx_process == NGX_PROCESS_SIGNALLER) {
return cycle;
} ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ngx_test_config) { if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
goto failed;
} } else if (!ngx_is_init_cycle(old_cycle)) { /*
* we do not create the pid file in the first ngx_init_cycle() call
* because we need to write the demonized process pid
*/ old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
ngx_core_module);
if (ccf->pid.len != old_ccf->pid.len
|| ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != )
{
/* new pid file name */ if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
goto failed;
} ngx_delete_pidfile(old_cycle);
}
} if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) {
goto failed;
} if (ngx_create_paths(cycle, ccf->user) != NGX_OK) {
goto failed;
} if (cycle->new_log.file == NULL) {
cycle->new_log.file = ngx_conf_open_file(cycle, &error_log);
if (cycle->new_log.file == NULL) {
goto failed;
}
} /* open the new files */ part = &cycle->open_files.part;
file = part->elts; for (i = ; /* void */ ; i++) { if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
file = part->elts;
i = ;
} if (file[i].name.len == ) {
continue;
} file[i].fd = ngx_open_file(file[i].name.data,
NGX_FILE_APPEND,
NGX_FILE_CREATE_OR_OPEN,
NGX_FILE_DEFAULT_ACCESS); ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, ,
"log: %p %d \"%s\"",
&file[i], file[i].fd, file[i].name.data); if (file[i].fd == NGX_INVALID_FILE) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
ngx_open_file_n " \"%s\" failed",
file[i].name.data);
goto failed;
} #if !(NGX_WIN32)
if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
"fcntl(FD_CLOEXEC) \"%s\" failed",
file[i].name.data);
goto failed;
}
#endif
} cycle->log = &cycle->new_log;
pool->log = &cycle->new_log; /* create shared memory */ part = &cycle->shared_memory.part;
shm_zone = part->elts; for (i = ; /* void */ ; i++) { if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
shm_zone = part->elts;
i = ;
} if (shm_zone[i].shm.size == ) {
ngx_log_error(NGX_LOG_EMERG, log, ,
"zero size shared memory zone \"%V\"",
&shm_zone[i].shm.name);
goto failed;
} shm_zone[i].shm.log = cycle->log; opart = &old_cycle->shared_memory.part;
oshm_zone = opart->elts; for (n = ; /* void */ ; n++) { if (n >= opart->nelts) {
if (opart->next == NULL) {
break;
}
opart = opart->next;
oshm_zone = opart->elts;
n = ;
} if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) {
continue;
} if (ngx_strncmp(shm_zone[i].shm.name.data,
oshm_zone[n].shm.name.data,
shm_zone[i].shm.name.len)
!= )
{
continue;
} if (shm_zone[i].tag == oshm_zone[n].tag
&& shm_zone[i].shm.size == oshm_zone[n].shm.size)
{
shm_zone[i].shm.addr = oshm_zone[n].shm.addr; if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data)
!= NGX_OK)
{
goto failed;
} goto shm_zone_found;
} ngx_shm_free(&oshm_zone[n].shm); break;
} if (ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK) {
goto failed;
} if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
goto failed;
} if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) {
goto failed;
} shm_zone_found: continue;
} /* handle the listening sockets */ if (old_cycle->listening.nelts) {
ls = old_cycle->listening.elts;
for (i = ; i < old_cycle->listening.nelts; i++) {
ls[i].remain = ;
} nls = cycle->listening.elts;
for (n = ; n < cycle->listening.nelts; n++) { for (i = ; i < old_cycle->listening.nelts; i++) {
if (ls[i].ignore) {
continue;
} if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr) == NGX_OK)
{
nls[n].fd = ls[i].fd;
nls[n].previous = &ls[i];
ls[i].remain = ; if (ls[n].backlog != nls[i].backlog) {
nls[n].listen = ;
} #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) /*
* FreeBSD, except the most recent versions,
* could not remove accept filter
*/
nls[n].deferred_accept = ls[i].deferred_accept; if (ls[i].accept_filter && nls[n].accept_filter) {
if (ngx_strcmp(ls[i].accept_filter,
nls[n].accept_filter)
!= )
{
nls[n].delete_deferred = ;
nls[n].add_deferred = ;
} } else if (ls[i].accept_filter) {
nls[n].delete_deferred = ; } else if (nls[n].accept_filter) {
nls[n].add_deferred = ;
}
#endif #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) if (ls[n].deferred_accept && !nls[n].deferred_accept) {
nls[n].delete_deferred = ; } else if (ls[i].deferred_accept != nls[n].deferred_accept)
{
nls[n].add_deferred = ;
}
#endif
break;
}
} if (nls[n].fd == -) {
nls[n].open = ;
}
} } else {
ls = cycle->listening.elts;
for (i = ; i < cycle->listening.nelts; i++) {
ls[i].open = ;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
if (ls[i].accept_filter) {
ls[i].add_deferred = ;
}
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
if (ls[i].deferred_accept) {
ls[i].add_deferred = ;
}
#endif
}
} if (ngx_open_listening_sockets(cycle) != NGX_OK) {
goto failed;
} if (!ngx_test_config) {
ngx_configure_listening_sockets(cycle);
} /* commit the new cycle configuration */ if (!ngx_use_stderr && cycle->log->file->fd != ngx_stderr) { if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
ngx_set_stderr_n " failed");
}
} pool->log = cycle->log; for (i = ; ngx_modules[i]; i++) {
if (ngx_modules[i]->init_module) {
if (ngx_modules[i]->init_module(cycle) != NGX_OK) {
/* fatal */
exit();
}
}
} /* close and delete stuff that lefts from an old cycle */ /* free the unnecessary shared memory */ opart = &old_cycle->shared_memory.part;
oshm_zone = opart->elts; for (i = ; /* void */ ; i++) { if (i >= opart->nelts) {
if (opart->next == NULL) {
goto old_shm_zone_done;
}
opart = opart->next;
oshm_zone = opart->elts;
i = ;
} part = &cycle->shared_memory.part;
shm_zone = part->elts; for (n = ; /* void */ ; n++) { if (n >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
shm_zone = part->elts;
n = ;
} if (oshm_zone[i].shm.name.len == shm_zone[n].shm.name.len
&& ngx_strncmp(oshm_zone[i].shm.name.data,
shm_zone[n].shm.name.data,
oshm_zone[i].shm.name.len)
== )
{
goto live_shm_zone;
}
} ngx_shm_free(&oshm_zone[i].shm); live_shm_zone: continue;
} old_shm_zone_done: /* close the unnecessary listening sockets */ ls = old_cycle->listening.elts;
for (i = ; i < old_cycle->listening.nelts; i++) { if (ls[i].remain || ls[i].fd == -) {
continue;
} if (ngx_close_socket(ls[i].fd) == -) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_close_socket_n " listening socket on %V failed",
&ls[i].addr_text);
} #if (NGX_HAVE_UNIX_DOMAIN) if (ls[i].sockaddr->sa_family == AF_UNIX) {
u_char *name; name = ls[i].addr_text.data + sizeof("unix:") - ; ngx_log_error(NGX_LOG_WARN, cycle->log, ,
"deleting socket %s", name); if (ngx_delete_file(name) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
ngx_delete_file_n " %s failed", name);
}
} #endif
} /* close the unnecessary open files */ part = &old_cycle->open_files.part;
file = part->elts; for (i = ; /* void */ ; i++) { if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
file = part->elts;
i = ;
} if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
continue;
} if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
ngx_close_file_n " \"%s\" failed",
file[i].name.data);
}
} ngx_destroy_pool(conf.temp_pool); if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) { /*
* perl_destruct() frees environ, if it is not the same as it was at
* perl_construct() time, therefore we save the previous cycle
* environment before ngx_conf_parse() where it will be changed.
*/ env = environ;
environ = senv; ngx_destroy_pool(old_cycle->pool);
cycle->old_cycle = NULL; environ = env; return cycle;
} if (ngx_temp_pool == NULL) {
ngx_temp_pool = ngx_create_pool(, cycle->log);
if (ngx_temp_pool == NULL) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ,
"could not create ngx_temp_pool");
exit();
} n = ;
ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool,
n * sizeof(ngx_cycle_t *));
if (ngx_old_cycles.elts == NULL) {
exit();
}
ngx_old_cycles.nelts = ;
ngx_old_cycles.size = sizeof(ngx_cycle_t *);
ngx_old_cycles.nalloc = n;
ngx_old_cycles.pool = ngx_temp_pool; ngx_cleaner_event.handler = ngx_clean_old_cycles;
ngx_cleaner_event.log = cycle->log;
ngx_cleaner_event.data = &dumb;
dumb.fd = (ngx_socket_t) -;
} ngx_temp_pool->log = cycle->log; old = ngx_array_push(&ngx_old_cycles);
if (old == NULL) {
exit();
}
*old = old_cycle; if (!ngx_cleaner_event.timer_set) {
ngx_add_timer(&ngx_cleaner_event, );
ngx_cleaner_event.timer_set = ;
} return cycle; failed: if (!ngx_is_init_cycle(old_cycle)) {
old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,ngx_core_module);
if (old_ccf->environment) {
environ = old_ccf->environment;
}
} /* rollback the new cycle configuration */ part = &cycle->open_files.part;
file = part->elts; for (i = ; /* void */ ; i++) { if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
file = part->elts;
i = ;
} if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
continue;
} if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
ngx_close_file_n " \"%s\" failed",
file[i].name.data);
}
} if (ngx_test_config) {
ngx_destroy_cycle_pools(&conf);
return NULL;
} ls = cycle->listening.elts;
for (i = ; i < cycle->listening.nelts; i++) {
if (ls[i].fd == - || !ls[i].open) {
continue;
} if (ngx_close_socket(ls[i].fd) == -) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_close_socket_n " %V failed",
&ls[i].addr_text);
}
} ngx_destroy_cycle_pools(&conf); return NULL;
}
修改配置参数之后,可以不重新启动服务,而可以生效。他把所有nginx的参数都放入到一个参数里面,如果修改,那么他会慢慢的修改过来。
3.4 ngx_cycle_s
文件:src/core/ngx_cycle.h
struct ngx_cycle_s {
void ****conf_ctx;//解析配置文件,
ngx_pool_t *pool;
ngx_log_t *log;
ngx_log_t new_log;
ngx_connection_t **files;
ngx_connection_t *free_connections;
ngx_uint_t free_connection_n;
ngx_queue_t reusable_connections_queue;
ngx_array_t listening;
ngx_array_t paths;
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;
};
3.5 ngx_core_conf_t 结构体
typedef struct {
ngx_flag_t daemon;
ngx_flag_t master;
ngx_msec_t timer_resolution;
ngx_int_t worker_processes; //进程数量
ngx_int_t debug_points;
ngx_int_t rlimit_nofile;
ngx_int_t rlimit_sigpending;
off_t rlimit_core;
int priority;
ngx_uint_t cpu_affinity_n;
uint64_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;
#if (NGX_THREADS)
ngx_int_t worker_threads;
size_t thread_stack_size;
#endif
} ngx_core_conf_t;
3.6 ngx_http_conf_cxt_t结构体
在src/http/ngx_http_config.h里面
typedef struct {
void **main_conf; //http的子模块
void **srv_conf; //所有server的参数
void **loc_conf; //所有url的参数
} ngx_http_conf_ctx_t;
NGINX源代码自我总结(一)的更多相关文章
- NGINX源代码剖析 之 CPU绑定(CPU亲和性)
作者:邹祁峰 邮箱:Qifeng.zou.job@gmail.com 博客:http://blog.csdn.net/qifengzou 日期:2014.06.12 18:44 转载请注明来自&quo ...
- nginx源代码学习资源(不断更新)
nginx源代码学习是一个痛苦又快乐的过程,以下列出了一些nginx的学习资源. 首先要做的当然是下载一份nginx源代码,能够从nginx官方站点下载一份最新的. 看了nginx源代码,发现这是一份 ...
- 菜鸟nginx源代码剖析数据结构篇(一)动态数组ngx_array_t
菜鸟nginx源代码剖析数据结构篇(一)动态数组ngx_array_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...
- 新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t
新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...
- 新秀nginx源代码分析数据结构篇(两) 双链表ngx_queue_t
nginx源代码分析数据结构篇(两) 双链表ngx_queue_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn. ...
- 菜鸟nginx源代码剖析数据结构篇(八) 缓冲区链表ngx_chain_t
菜鸟nginx源代码剖析数据结构篇(八) 缓冲区链表 ngx_chain_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog. ...
- nginx源代码分析之内存池实现原理
建议看本文档时结合nginx源代码. 1.1 什么是内存池?为什么要引入内存池? 内存池实质上是接替OS进行内存管理.应用程序申请内存时不再与OS打交道.而是从内存池中申请内存或者释放内存到内存池 ...
- Nginx源代码分析—业务流程
Nginx源代码分析-业务流程 到此为止,我们如果ngx_init_cycle已经结束.我们临时无论他做了什么,我们从他做的效果进入. 从常理上来讲,假设一个请求到达,那么我们须要接受这个请求,那么就 ...
- 《nginx源代码解析》系列分享专栏
<nginx源代码解析>系列分享专栏 解析nginx源代码,从main函数开始,一步步解读nginx运行原理,同时进行nginx第三方模块的开发,努力做到知其然,知其所以然 <ngi ...
随机推荐
- cloudera项目源代码
以下项目都需要安装git,Linux的git还是比较容易安装的,windows的git安装参考项目区域:软件版本控制-在Windows中使用Git视频介绍 git相关软件安装参考win7安装 git软 ...
- ios成长之每日一遍(day 1)
Hello world开始. 这里不讨论如何创建项目导入项目.由于趁上班时间打酱油所以也不谈细节, 只谈具体项目的实现与关键流程的解析, 只供本人实际程况使用.不喜请移驾. 首先来谈谈 AppDele ...
- 详解Java多线程编程中LockSupport
LockSupport是用来创建锁和其他同步类的基本线程阻塞原语. LockSupport中的park() 和 unpark() 的作用分别是阻塞线程和解除阻塞线程,而且park()和unpark() ...
- [Android] Implementation vs API dependency
原文链接: https://jeroenmols.com/blog/2017/06/14/androidstudio3/ https://blog.csdn.net/lonewolf521125/ar ...
- PHPUnit安装
From : http://blog.csdn.net/ruby97/article/details/8868197
- cplusplus 库 在线管理; 类似于 python的 pip install 、nodejs 的npm模块
cplusplus 库 在线管理: 类似于 python的 pip install .nodejs 的npm模块 还有 apache 经常使用的 Apache Ivy 项目依赖管理工具/Maven 这 ...
- emouse思·睿—评论与观点整理之一
虽说我主要做的硬件,平时的兴趣爱好比较关注移动互联网,混迹于虎嗅.爱范儿.雷锋网.36Kr.cnBeta.瘾科技.i黑马.TechWeb等这类科技以及创业媒体,遗憾的是系统的去写的并不多,好在还算充分 ...
- Zindex和png
Z轴在元素设置position为absolute或relative后被激活,起大小由z-index设置,z-index越大,元素位置越靠上.如果多个元素的z-index值相同,那么html标签中后出现 ...
- [leetcode]Jump Game @ Python
原题地址:https://oj.leetcode.com/problems/jump-game/ 题意: Given an array of non-negative integers, you ar ...
- C++模拟键盘消息
实现功能:在现有DLL程序中向特定的EXE窗口中发送模拟键盘的消息 使用API根据窗口标题递归查找特定的窗口句柄,之后模拟调用. 注意:keybd_event函数不能在VS下使用,所以用SendInp ...