【Nginx 源码学习】平滑重启,源码追踪

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 + 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;

}

n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;

if (ngx_array_init(&cycle->paths, pool, n, sizeof(ngx_path_t *))

!= NGX_OK)

{

ngx_destroy_pool(pool);

return NULL;

}

ngx_memzero(cycle->paths.elts, n * sizeof(ngx_path_t *));

if (ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t))

!= NGX_OK)

{

ngx_destroy_pool(pool);

return NULL;

}

ngx_rbtree_init(&cycle->config_dump_rbtree, &cycle->config_dump_sentinel,

ngx_str_rbtree_insert_value);

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;

}

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;

}

n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;

if (ngx_array_init(&cycle->listening, pool, n, sizeof(ngx_listening_t))

!= NGX_OK)

{

ngx_destroy_pool(pool);

return NULL;

}

ngx_memzero(cycle->listening.elts, n * sizeof(ngx_listening_t));

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) == -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);

if (ngx_cycle_modules(cycle) != NGX_OK) {

ngx_destroy_pool(pool);

return NULL;

}

for (i = 0; cycle->modules[i]; i++) {

if (cycle->modules[i]->type != NGX_CORE_MODULE) {

continue;

}

module = cycle->modules[i]->ctx;

if (module->create_conf) {

rv = module->create_conf(cycle);

if (rv == NULL) {

ngx_destroy_pool(pool);

return NULL;

}

cycle->conf_ctx[cycle->modules[i]->index] = rv;

}

}

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;

#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;

}

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; cycle->modules[i]; i++) {

if (cycle->modules[i]->type != NGX_CORE_MODULE) {

continue;

}

module = cycle->modules[i]->ctx;

if (module->init_conf) {

if (module->init_conf(cycle,

cycle->conf_ctx[cycle->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) != 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 (ngx_log_open_default(cycle) != NGX_OK) {

goto failed;

}

/* open the new 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;

/* create 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].noreuse)

{

shm_zone[i].shm.addr = oshm_zone[n].shm.addr;

#if (NGX_WIN32)

shm_zone[i].shm.handle = oshm_zone[n].shm.handle;

#endif

if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data)

!= NGX_OK)

{

goto failed;

}

goto shm_zone_found;

}

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 = 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 (ls[i].remain) {

continue;

}

if (ls[i].type != nls[n].type) {

continue;

}

if (ngx_cmp_sockaddr(nls[n].sockaddr, nls[n].socklen,

ls[i].sockaddr, ls[i].socklen, 1)

== NGX_OK)

{

nls[n].fd = ls[i].fd;

nls[n].previous = &ls[i];

ls[i].remain = 1;

if (ls[i].backlog != nls[n].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[i].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

#if (NGX_HAVE_REUSEPORT)

if (nls[n].reuseport && !ls[i].reuseport) {

nls[n].add_reuseport = 1;

}

#endif

break;

}

}

if (nls[n].fd == (ngx_socket_t) -1) {

nls[n].open = 1;

#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)

if (nls[n].accept_filter) {

nls[n].add_deferred = 1;

}

#endif

#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)

if (nls[n].deferred_accept) {

nls[n].add_deferred = 1;

}

#endif

}

}

} 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);

}

/* commit the new cycle configuration */

if (!ngx_use_stderr) {

(void) ngx_log_redirect_stderr(cycle);

}

pool->log = cycle->log;

if (ngx_init_modules(cycle) != NGX_OK) {

/* fatal */

exit(1);

}

/* 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 = 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) {

continue;

}

if (ngx_strncmp(oshm_zone[i].shm.name.data,

shm_zone[n].shm.name.data,

oshm_zone[i].shm.name.len)

!= 0)

{

continue;

}

if (oshm_zone[i].tag == shm_zone[n].tag

&& oshm_zone[i].shm.size == shm_zone[n].shm.size

&& !oshm_zone[i].noreuse)

{

goto live_shm_zone;

}

break;

}

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 == (ngx_socket_t) -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)) {

ngx_destroy_pool(old_cycle->pool);

cycle->old_cycle = NULL;

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;

if (ngx_array_init(&ngx_old_cycles, ngx_temp_pool, n,

sizeof(ngx_cycle_t *))

!= NGX_OK)

{

exit(1);

}

ngx_memzero(ngx_old_cycles.elts, n * sizeof(ngx_cycle_t *));

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:

写在最后

学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

最后再分享的一些BATJ等大厂20、21年的面试题,把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌

Mybatis面试专题

蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌

MySQL面试专题

蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌

并发编程面试专题

x_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) {

ngx_destroy_pool(old_cycle->pool);

cycle->old_cycle = NULL;

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;

if (ngx_array_init(&ngx_old_cycles, ngx_temp_pool, n,

sizeof(ngx_cycle_t *))

!= NGX_OK)

{

exit(1);

}

ngx_memzero(ngx_old_cycles.elts, n * sizeof(ngx_cycle_t *));

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:

写在最后

学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

最后再分享的一些BATJ等大厂20、21年的面试题,把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

[外链图片转存中…(img-MgKy4fFZ-1718782924727)]

Mybatis面试专题

[外链图片转存中…(img-iZD9bUB1-1718782924728)]

MySQL面试专题

[外链图片转存中…(img-6j7aSyBB-1718782924729)]

并发编程面试专题

  • 26
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要安装nginx码包,您可以按照以下步骤进行操作: 1. 首先,您需要下载nginx码包。您可以从官方网站上下载最新版本的码包。您可以在http://nginx.org/download/找到最新的码包下载链接。 2. 下载完成后,解压码包。您可以使用tar命令来解压文件。例如,如果您的码包是nginx-1.20.1.tar.gz,您可以使用以下命令进行解压: ``` tar -zxvf nginx-1.20.1.tar.gz ``` 3. 进入解压后的目录: ``` cd nginx-1.20.1 ``` 4. 在码目录中,执行configure命令进行配置。该命令将根据您的系统环境进行一些必要的配置: ``` ./configure ``` 5. 配置完成后,运行make命令编译码: ``` make ``` 6. 编译完成后,运行make install命令将nginx安装到系统中: ``` make install ``` 7. 安装完成后,您可以检查是否成功安装了nginx。您可以使用id命令来检查是否存在nginx用户: ``` id nginx ``` 以上就是nginx码安装的一般步骤。请注意,这里只提供了基本的安装步骤,具体的安装过程可能会因系统环境和配置需求而有所不同。建议您在安装前阅读官方文档或参考更详细的安装指南以确保正确安装nginx。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [nginx码安装](https://blog.csdn.net/weixin_49185464/article/details/127326489)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值