转自:http://blog.csdn.net/joescott/article/details/17019647
ngx_init_cycle是nginx启动比较核心的一部分功能, 很多的变量都在这个过程进行初始化。 下面从代码的层面详细介绍下,这个过程做了哪些事情。源代码位于src/core/ngx_cycle.h|c.
首先看下几个相关的数据结构:
1. ngx_cycle_t 数据结构:
- typedef struct ngx_cycle_s ngx_cycle_t;
- struct ngx_cycle_s {
- void ****conf_ctx; //配置上下文数组(含所有模块)
- ngx_pool_t *pool; //内存池
- ngx_log_t *log; //日志
- ngx_log_t new_log; //中转的日志,在ngx_init_cycle的时候产生一个日志初始化,再 log = &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; //配置文件,如:nginx.conf
- ngx_str_t conf_param; //配置参数
- ngx_str_t conf_prefix; //配置前缀
- ngx_str_t prefix; //前缀
- ngx_str_t lock_file; //锁文件的路径
- ngx_str_t hostname; //主机名
- };
2. ngx_pool_t数据类型:
内存池数据结构请参看内存池的文章介绍。
3. ngx_log_t日志对象数据类型 :
参见日志对象的分析文章。
4. 先分析ngx_init_cycle()方法
4.1 声明变量:
- 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];
4.3 创建内存池pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log); 此处创建大小为NGX_CYCLE_POOL_SIZE=16384B的内存池。
4.4 在刚创建的内存池里边为ngx_cycle_t分配空间: cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
4.5 简单初始化,如记录pool指针、log指针
- cycle->pool = pool;
- cycle->log = log;
- cycle->new_log.log_level = NGX_LOG_ERR;
- cycle->old_cycle = old_cycle;
4.6 初始化配置前缀、前缀、配置文件、配置参数等字符串, 从旧的old_cycle里边将一些数据拷贝给cycle对象。
- cycle->conf_prefix.len = old_cycle->conf_prefix.len;
- cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix); // 从old_cycle中拷贝配置前缀数据到新的cycle配置数据中。
- 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); // 从old_cycle中拷贝前缀数据到新的cycle中
- 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 + 1);
- 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 + 1);
- 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;
- }
4.7 初始化pathes数组
- n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10; // 如果旧的cycle对象有路径数组元素的数目, 那么使用原来的, 否则使用默认的10
- 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 = 0;
- cycle->paths.size = sizeof(ngx_path_t *);
- cycle->paths.nalloc = n;
- cycle->paths.pool = pool; // 这里都把内存池给赋值给对象的内存池属性, 因为在内存和资源管理方面,nginx委托内存池统一管理, 这里可以通过具体的对象找到它用的内存池对象, 方便实现内存和资源方面的管理。
4.8 初始化open_files链表
- 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 = 20;
- }
- if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
- != NGX_OK)
- {
- ngx_destroy_pool(pool);
- return NULL;
- }
4.9 初始化shared_memory链表
- 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 = 1;
- }
- if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
- != NGX_OK)
- {
- ngx_destroy_pool(pool);
- return NULL;
- }
4.10 初始化listening数组
- n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;
- 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 = 0;
- cycle->listening.size = sizeof(ngx_listening_t);
- cycle->listening.nalloc = n;
- cycle->listening.pool = pool;
4.11 初始化resuable_connections_queue队列
- ngx_queue_init(&cycle->reusable_connections_queue);
4.12 从pool为conf_ctx分配空间
- cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
- if (cycle->conf_ctx == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
4.13 初始化hostname字符串
- if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
- 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 - 1] = '\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);
4.14 调用core模块的create_conf() , 配置存于cycle的conf_ctx数组中, 键值为编译后的核心模块的index编号
- for (i = 0; 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;
- }
- }
4.15 配置对象的内存池创建,配置文件解析
- senv = environ;
- ngx_memzero(&conf, sizeof(ngx_conf_t));
- /* STUB: init array ? */
- conf.args = ngx_array_create(pool, 10, 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;
- 0
- log->log_level = NGX_LOG_DEBUG_ALL;
- if
- 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;
- }
- if (ngx_test_config && !ngx_quiet_mode) {
- ngx_log_stderr(0, "the configuration file %s syntax is ok",
- cycle->conf_file.data);
- }
- for (i = 0; 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;
- }
- }
- }
4. 17
- 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) != 0)
- {
- /* 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;
- }
- }
4.18 遍历open_files链表中的每一个文件并打开
- part = &cycle->open_files.part;
- file = part->elts;
- for (i = 0; /* void */ ; i++) {
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- file = part->elts;
- i = 0;
- }
- if (file[i].name.len == 0) {
- 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, 0,
- "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) == -1) {
- 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;
4.19 创建共享内存并初始化(新旧shared_memory链表的比较,相同的共享内存保留,旧的不同的共享内存被释放,新的被创建)
- part = &cycle->shared_memory.part;
- shm_zone = part->elts;
- for (i = 0; /* void */ ; i++) {
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- shm_zone = part->elts;
- i = 0;
- }
- if (shm_zone[i].shm.size == 0) {
- ngx_log_error(NGX_LOG_EMERG, log, 0,
- "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 = 0; /* void */ ; n++) {
- if (n >= opart->nelts) {
- if (opart->next == NULL) {
- break;
- }
- opart = opart->next;
- oshm_zone = opart->elts;
- n = 0;
- }
- 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)
- != 0)
- {
- 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;
- }
4.20 (尝试5遍)遍历listening数组并打开所有侦听sockets(socket()->setsockopt()->bind()->listen())
- if (old_cycle->listening.nelts) {
- ls = old_cycle->listening.elts;
- for (i = 0; i < old_cycle->listening.nelts; i++) {
- ls[i].remain = 0;
- }
- nls = cycle->listening.elts;
- for (n = 0; n < cycle->listening.nelts; n++) {
- for (i = 0; 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 = 1;
- if (ls[n].backlog != nls[i].backlog) {
- nls[n].listen = 1;
- }
- #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)
- != 0)
- {
- nls[n].delete_deferred = 1;
- nls[n].add_deferred = 1;
- }
- } else if (ls[i].accept_filter) {
- nls[n].delete_deferred = 1;
- } else if (nls[n].accept_filter) {
- nls[n].add_deferred = 1;
- }
- #endif
- #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
- if (ls[n].deferred_accept && !nls[n].deferred_accept) {
- nls[n].delete_deferred = 1;
- } else if (ls[i].deferred_accept != nls[n].deferred_accept)
- {
- nls[n].add_deferred = 1;
- }
- #endif
- break;
- }
- }
- if (nls[n].fd == -1) {
- nls[n].open = 1;
- }
- }
- } else {
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
- ls[i].open = 1;
- #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
- if (ls[i].accept_filter) {
- ls[i].add_deferred = 1;
- }
- #endif
- #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
- if (ls[i].deferred_accept) {
- ls[i].add_deferred = 1;
- }
- #endif
- }
- }
- if (ngx_open_listening_sockets(cycle) != NGX_OK) {
- goto failed;
- }
- if (!ngx_test_config) {
- ngx_configure_listening_sockets(cycle);
- }
4.21 提交新的cycle配置,并调用所有模块的init_module(实际上只有ngx_event_core_module模块定义了该callback,即只有ngx_event_module_init()被调用)
- /* 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;
- // 提交新的cycle配置,
- // 并调用所有模块的init_module(实际上只有ngx_event_core_module模块定义了该callback,即只有ngx_event_module_init()被调用)
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->init_module) {
- if (ngx_modules[i]->init_module(cycle) != NGX_OK) {
- /* fatal */
- exit(1);
- }
- }
- }
4.22 关闭或删除残留在old_cycle中的资源: 释放多余的共享内存, 关闭多余的侦听sockets,关闭多余的打开文件
- opart = &old_cycle->shared_memory.part;
- oshm_zone = opart->elts;
- for (i = 0; /* void */ ; i++) {
- if (i >= opart->nelts) {
- if (opart->next == NULL) {
- goto old_shm_zone_done;
- }
- opart = opart->next;
- oshm_zone = opart->elts;
- i = 0;
- }
- part = &cycle->shared_memory.part;
- shm_zone = part->elts;
- for (n = 0; /* void */ ; n++) {
- if (n >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- shm_zone = part->elts;
- n = 0;
- }
- 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)
- == 0)
- {
- 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 = 0; i < old_cycle->listening.nelts; i++) {
- if (ls[i].remain || ls[i].fd == -1) {
- continue;
- }
- if (ngx_close_socket(ls[i].fd) == -1) {
- 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:") - 1;
- ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
- "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 = 0; /* void */ ; i++) {
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- file = part->elts;
- i = 0;
- }
- 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(128, cycle->log);
- if (ngx_temp_pool == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "could not create ngx_temp_pool");
- exit(1);
- }
- n = 10;
- ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool,
- n * sizeof(ngx_cycle_t *));
- if (ngx_old_cycles.elts == NULL) {
- exit(1);
- }
- ngx_old_cycles.nelts = 0;
- 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) -1;
- }
- ngx_temp_pool->log = cycle->log;
- old = ngx_array_push(&ngx_old_cycles);
- if (old == NULL) {
- exit(1);
- }
- *old = old_cycle;
- if (!ngx_cleaner_event.timer_set) {
- ngx_add_timer(&ngx_cleaner_event, 30000);
- ngx_cleaner_event.timer_set = 1;
- }
- 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;
- }
- }
4.23 回退新的cycle配置
- /* rollback the new cycle configuration */
- part = &cycle->open_files.part;
- file = part->elts;
- for (i = 0; /* void */ ; i++) {
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- file = part->elts;
- i = 0;
- }
- 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 = 0; i < cycle->listening.nelts; i++) {
- if (ls[i].fd == -1 || !ls[i].open) {
- continue;
- }
- if (ngx_close_socket(ls[i].fd) == -1) {
- 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);
http {
server {
location /xxx {
user_search /usr/local/nginx/conf/reverse_proxy.properties;
}
...
看来这样的 request 不是 hard code 的,而是在 nginx 配置文件中配的,于是就想搞清楚 nginx.conf 文件在哪被加载和解析的,以及解析后放到哪个数据结构中的。
在转载的这篇帖子中,“ 4.15 配置对象的内存池创建,配置文件解析”章节中,第36行代码就是解析 nginx.conf 的地方。
待续……