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

相关文章

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

Nginx中配置使用非默认80端口进行服务的完整指南

《Nginx中配置使用非默认80端口进行服务的完整指南》在实际生产环境中,我们经常需要将Nginx配置在其他端口上运行,本文将详细介绍如何在Nginx中配置使用非默认端口进行服务,希望对大家有所帮助... 目录一、为什么需要使用非默认端口二、配置Nginx使用非默认端口的基本方法2.1 修改listen指令

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec

Nginx添加内置模块过程

《Nginx添加内置模块过程》文章指导如何检查并添加Nginx的with-http_gzip_static模块:确认该模块未默认安装后,需下载同版本源码重新编译,备份替换原有二进制文件,最后重启服务验... 目录1、查看Nginx已编辑的模块2、Nginx官网查看内置模块3、停止Nginx服务4、Nginx

MySQL 临时表与复制表操作全流程案例

《MySQL临时表与复制表操作全流程案例》本文介绍MySQL临时表与复制表的区别与使用,涵盖生命周期、存储机制、操作限制、创建方法及常见问题,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小... 目录一、mysql 临时表(一)核心特性拓展(二)操作全流程案例1. 复杂查询中的临时表应用2. 临时

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

通过配置nginx访问服务器静态资源的过程

《通过配置nginx访问服务器静态资源的过程》文章介绍了图片存储路径设置、Nginx服务器配置及通过http://192.168.206.170:8007/a.png访问图片的方法,涵盖图片管理与服务... 目录1.图片存储路径2.nginx配置3.访问图片方式总结1.图片存储路径2.nginx配置