nginx main流程分析

2024-08-24 16:18
文章标签 分析 流程 nginx main

本文主要是介绍nginx 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;
/*
第一个函数ngx_debug_init(),这个函数主要是作为初始化debug用的,nginx中的debug,主要是对内存池分配管理方面的debug,因为作为一个应用程序,最容易出现bug的地方也是内存管理这块。在Linux版本中,这个函数只是一个空定义(src/os/unix/ngx_linux_config.h)。
#define ngx_debug_init()
*/
ngx_debug_init();
/*
*我们来到程序的第208行,ngx_strerror_init(),该函数的定义在文件src/os/unix/ngx_errno.c中。
*该函数主要初始化系统中错误编号对应的含义,这样初始化中进行对应的好处是,当出现错误,
*不用再去调用strerror()函数来获取错误原因,而直接可以根据错误编号找到对应的错误原因,
*可以提高运行时的执行效率。从这里可以看到,nginx开发者的别有用心,对于微小的性能提升也毫不放过。 */
if (ngx_strerror_init() != NGX_OK) {
return 1;
}
//获得运行时选项
if (ngx_get_options( argc, argv ) != NGX_OK) {
return 1;
}
if (ngx_show_version) {
ngx_write_stderr( "nginx version: " NGINX_VER NGX_LINEFEED );
if (ngx_show_help) {
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 0;
}
}
/* TODO */ ngx_max_sockets = -1;
//初始化系统时间
ngx_time_init();
#if (NGX_PCRE)
ngx_regex_init();
#endif
ngx_pid = ngx_getpid();
//初始化日志信息
log = ngx_log_init(ngx_prefix);
if (log == NULL) {
return 1;
}
/* STUB */
#if (NGX_OPENSSL)
ngx_ssl_init( log);
#endif
/*
* init_cycle->log is required for signal handlers and
* ngx_process_options()
*/
/*
ngx_string.h 第86行
#define ngx_memzero(buf, n)       (void) memset(buf, 0, n)
ngx_cycle_s 机构体:ngx_cycle.h 第37行
*/
ngx_memzero(& init_cycle, sizeof (ngx_cycle_t));
//开始初始化ngx_cycle_s *init_cycle对象
init_cycle. log = log ;
ngx_cycle = & init_cycle;
// 为ngx_cycle 创建内存池 ,ngx_pool我们在另一篇博客中再讲
init_cycle. pool = ngx_create_pool(1024, log );
if (init_cycle. pool == NULL ) {
return 1;
}
// 保存进程参数到init_cycle中
if (ngx_save_argv(& init_cycle, argc , argv) != NGX_OK) {
return 1;
}
// 处理进程参数
if (ngx_process_options(& init_cycle) != NGX_OK) {
return 1;
}
// 获取系统配置信息 (分页大小,CPU 个数,CPU 制造商,文件符最大数等)  
if (ngx_os_init( log) != NGX_OK) {
return 1;
}
/*
* ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
*/
// 初始化循环冗余检验表,验证接收数据
if (ngx_crc32_table_init() != NGX_OK) {
return 1;
}
//通过环境变量NGINX完成socket的继承,这些继承来的socket会放到init_cycyle的listening数组中。
if (ngx_add_inherited_sockets(& init_cycle) != NGX_OK) {
return 1;
}
ngx_max_module = 0;
/**
* nginx把所有模块(ngx_module_t)存放到ngx_modules数组中,这个数组在nginx源码路
* 径的objs/ngx_modules.c中,是在运行configure脚本后生成的。index属性就是该模块
* 在ngx_modules数组中的下标。同时nginx把所有的core module的配置结构存放到ngx_cycle的
* conf_ctx数组中,index也是该模块的配置结构在ngx_cycle->conf_ctx数组中的下标。
**/
for (i = 0; ngx_modules[ i]; i ++) {
ngx_modules[ i]->index = ngx_max_module++;
}
// 初始化init cycle 变量,这是个牛逼的结构 
cycle = ngx_init_cycle(& init_cycle);
if (cycle == NULL) {
if (ngx_test_config) {
ngx_log_stderr(0, "configuration file %s test failed" ,
init_cycle.conf_file .data);
}
return 1;
}
if (ngx_test_config) {
if (!ngx_quiet_mode) {
ngx_log_stderr(0, "configuration file %s test is successful" ,
cycle->conf_file .data);
}
return 0;
}
if (ngx_signal) {
return ngx_signal_process(cycle , ngx_signal);
}
ngx_os_status( cycle->log );
ngx_cycle = cycle;
// 获取core module 的配置指针  
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 1;
}
if (!ngx_inherited && ccf->daemon) {
if (ngx_daemon(cycle ->log) != NGX_OK) {
return 1;
}
ngx_daemonized = 1;
}
if (ngx_inherited) {
ngx_daemonized = 1;
}
#endif
if (ngx_create_pidfile(& ccf->pid , cycle-> log) != NGX_OK) {
return 1;
}
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 1;
}
}
//检查log文件句柄
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 = 0;
if (ngx_process == NGX_PROCESS_SINGLE) {
ngx_single_process_cycle( cycle);
} else {
ngx_master_process_cycle( cycle);
}
return 0;
}


这篇关于nginx main流程分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1102976

相关文章

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

Nginx中配置HTTP/2协议的详细指南

《Nginx中配置HTTP/2协议的详细指南》HTTP/2是HTTP协议的下一代版本,旨在提高性能、减少延迟并优化现代网络环境中的通信效率,本文将为大家介绍Nginx配置HTTP/2协议想详细步骤,需... 目录一、HTTP/2 协议概述1.HTTP/22. HTTP/2 的核心特性3. HTTP/2 的优

详解nginx 中location和 proxy_pass的匹配规则

《详解nginx中location和proxy_pass的匹配规则》location是Nginx中用来匹配客户端请求URI的指令,决定如何处理特定路径的请求,它定义了请求的路由规则,后续的配置(如... 目录location 的作用语法示例:location /www.chinasem.cntestproxy

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各