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

相关文章

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

Olingo分析和实践之ODataImpl详细分析(重要方法详解)

《Olingo分析和实践之ODataImpl详细分析(重要方法详解)》ODataImpl.java是ApacheOlingoOData框架的核心工厂类,负责创建序列化器、反序列化器和处理器等组件,... 目录概述主要职责类结构与继承关系核心功能分析1. 序列化器管理2. 反序列化器管理3. 处理器管理重要方

使用Go实现文件复制的完整流程

《使用Go实现文件复制的完整流程》本案例将实现一个实用的文件操作工具:将一个文件的内容完整复制到另一个文件中,这是文件处理中的常见任务,比如配置文件备份、日志迁移、用户上传文件转存等,文中通过代码示例... 目录案例说明涉及China编程知识点示例代码代码解析示例运行练习扩展小结案例说明我们将通过标准库 os

Nginx安全防护的多种方法

《Nginx安全防护的多种方法》在生产环境中,需要隐藏Nginx的版本号,以避免泄漏Nginx的版本,使攻击者不能针对特定版本进行攻击,下面就来介绍一下Nginx安全防护的方法,感兴趣的可以了解一下... 目录核心安全配置1.编译安装 Nginx2.隐藏版本号3.限制危险请求方法4.请求限制(CC攻击防御)

nginx中端口无权限的问题解决

《nginx中端口无权限的问题解决》当Nginx日志报错bind()to80failed(13:Permissiondenied)时,这通常是由于权限不足导致Nginx无法绑定到80端口,下面就来... 目录一、问题原因分析二、解决方案1. 以 root 权限运行 Nginx(不推荐)2. 为 Nginx

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

解决1093 - You can‘t specify target table报错问题及原因分析

《解决1093-Youcan‘tspecifytargettable报错问题及原因分析》MySQL1093错误因UPDATE/DELETE语句的FROM子句直接引用目标表或嵌套子查询导致,... 目录报js错原因分析具体原因解决办法方法一:使用临时表方法二:使用JOIN方法三:使用EXISTS示例总结报错原