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 ...
随机推荐
- ibatis.net:第八天,QueryForDictionary
xml <statement id="FindOrdersByCustomer" parameterClass="string" resultClass= ...
- 关于面试总结8-http协议相关面试题
前言 在PC浏览器的地址栏输入一串URL,然后按Enter键这个页面渲染出来,这个过程中都发生了什么事?这个是很多面试官喜欢问的一个问题 如果测试只是停留在表面上点点点,不知道背后的逻辑,是无法发现隐 ...
- jquery 带农历天干地支的日期选择控件
效果图:
- SharePoint Online 创建列表库
前言 本文介绍如何在Office 365中创建列表库,以及列表库的一些基本设置. 正文 通过登录地址登录到Office 365的SharePoint Online站点中,我们可以在右上角的设置菜单中, ...
- SharePoint 2013 安装.NET Framework 3.5 报错
环境描述 操作系统:Windows Server 2012 R2 Datacenter版本 安装报错 中途接手安装SharePoint Server 2013 with sp1,配置向导报错如下: A ...
- YAML 语言教程
编程免不了要写配置文件,怎么写配置也是一门学问. YAML 是专门用来写配置文件的语言,非常简洁和强大,远比 JSON 格式方便. 本文介绍 YAML 的语法,以 JS-YAML 的实现为例.你可以去 ...
- MVC的Ajax异步请求
@using (Ajax.BeginForm("GetTime","order",new AjaxOptions() { Confirm="你确认这么 ...
- 相声段子:How Are You
/**************************************************************** File name : HowAreYou Author : 叶飞影 ...
- 如何让Domain里的其他系统通过DC来进行外网的DNS解析
搭建一个测试环境, 一般会建立一个DC, 然后再建立许多虚机加入到这个新DC的domain. 我们有个DNS服务器的地址, 哪台虚机要上外网, 就把这个DNS地址填到这台虚机的DNS server a ...
- spring boot整合mybatis+mybatis-plus
Spring boot对于我来说是一个刚接触的新东西,学习过程中,发现这东西还是很容易上手的,Spring boot没配置时会默认使用Spring data jpa,这东西可以说一个极简洁的工具,可是 ...