主要介绍Nginx的启动过程,可以在/core/nginx.c中找到Nginx的主函数main(),那么就从这里开始分析Nginx的启动过程。

涉及到的基本函数

源码:

 View
Code

  Nginx的启动包括了很多的初始化和处理函数。这些函数相对来说,有一部分非常复杂,暂且从简单开始,从整体上对Ngixnd的启动有一个了解,方便日后的分析与学习。

  主要函数:

//完成socket的继承 
static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle); 
//对参数选项进行处理 
static ngx_int_t ngx_get_options(int argc, char *const *argv);
 //初始化ngx_cycle内的部分内容 
static ngx_int_t ngx_process_options(ngx_cycle_t *cycle); 
//命令行参数保存到ngx_os_argv、ngx_argc以及ngx_argv全局的变量中 
static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
//创建模块的配置信息 
static void *ngx_core_module_create_conf(ngx_cycle_t *cycle); 
//初始化配置信息 
static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf); 
static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 
static char *ngx_set_env(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 
//设置优先级 
static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 
//设置CPU亲和性 
static char *ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 
//设置worker进程 
static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

Nginx启动的主要流程

  下图为Nginx的启动时函数的调用过程,其中大部分都是为了Nginx启动的初始化部分。从错误处理、参数设置、时间设置等方面进行初始化,并注册了我们需要的模块,最后根据信号选择单任务模式还是master-worker模式。

  流程图:

初始化

  主函数在开始对系统错误、参数、时间、系统变量、日志等进行了初始化。

//初始化系统中错误编号对应的含义
ngx_strerror_init(); 
//对参数选项进行处理 
ngx_get_options(argc, argv); 
//时间初始化 
ngx_time_init(); 
//重置pcre内存管理的接口 
ngx_regex_init(); 
//日志初始化 
ngx_log_init(ngx_prefix); 
//创建内存池 
ngx_create_pool(1024, log); 
//保存变量 
ngx_save_argv(); 
//初始化ngx_cycle的prefix, conf_prefix, conf_file, conf_param 
ngx_process_options(); 
//初始化系统相关变量,如内存页面大小,ngx_pagesize,ngx_cacheline_size,最大连接数ngx_max_sockets等 
ngx_os_init(); 
//初始化CRC表(后续的CRC校验通过查表进行,效率高) 
ngx_crc32_table_init();

主要工作

  初始化完成后,需要先调用ngx_add_inherited_sockets函数继承socket,并储存在Listening数组中,在运行时候进行监听。之后就可以调用ngx_init_cycle来初始化ngx_cycle结构体,这个结构体用来存储所有的连接,具体如下:

struct ngx_cycle_s {


void ****conf_ctx;
//配置上下文数组(含所有模块)

ngx_pool_t *pool; //内存池


ngx_log_t *log; //日志


ngx_log_t 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; //配置文件   
 ngx_str_t                 conf_param; //配置参数 
 ngx_str_t                 conf_prefix; //配置前缀 
 ngx_str_t                 prefix; //前缀 
 ngx_str_t                 lock_file; //锁文件 
 ngx_str_t                 hostname;

  调用ngx_init_signals来注册信号。

//信号种类 
#define NGX_PROCESS_SINGLE 0 
#define NGX_PROCESS_MASTER 1 
#define NGX_PROCESS_SIGNALLER 2 
#define NGX_PROCESS_WORKER 3 
#define NGX_PROCESS_HELPER 4

  在进入处理之前,还要调用ngx_create_pidfile来记录进程id。最后,根据接收到的信号,来判断调用ngx_single_process_cycle还是ngx_master_process_cycle(master-worker模式)。

if (ngx_process == NGX_PROCESS_SINGLE) {
ngx_single_process_cycle(cycle);
} else {
ngx_master_process_cycle(cycle);
}

  其中,守护进程函数为ngx_daemon,位于src/os/unix/Ngx_daemon.c

//daemon 
ngx_int_t
ngx_daemon(ngx_log_t *log)
     int fd; 
     switch (fork()) { 
 case -1:
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed"); 
 return NGX_ERROR; 
 case 0: 
 breakdefault:
exit(0);
} ngx_pid = ngx_getpid();   //取得进程识别码 
 
 if (setsid() == -1) { //子进程将重新获得一个新的会话(session)id 
 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed"); 
 return NGX_ERROR;
 }

    umask(0);

    fd = open("/dev/null", O_RDWR); 
 if (fd == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, 
 "open(\"/dev/null\") failed"); 
 return NGX_ERROR;
 
 if (dup2(fd, STDIN_FILENO) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, 
 "dup2(STDIN) failed");
 return NGX_ERROR;
 
 if (dup2(fd, STDOUT_FILENO) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, 
 "dup2(STDOUT) failed"); 
 return NGX_ERROR;
 } 
#if 0 
 
 if (dup2(fd, STDERR_FILENO) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, 
 "dup2(STDERR) failed"); 
 return NGX_ERROR;
#endif 
  
 if (fd > STDERR_FILENO) { 
 if (close(fd) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed"); 
 return NGX_ERROR;
}
 return NGX_OK;
}

参考

http://blog.xiuwz.com/2011/11/29/nginx-pcre-conflict/

http://blog.csdn.net/liuhongxiangm/article/details/8107613

http://www.4os.org/index.php/2010/11/25/nginx%E5%90%AF%E5%8A%A8%E5%88%9D%E5%A7%8B%E5%8C%96%E8%BF%87%E7%A8%8B%E8%BD%AC%E8%BD%BD/

http://blog.csdn.net/livelylittlefish/article/details/7243718

Nginx的启动过程的更多相关文章

  1. 【Nginx】启动过程

    从应用程序的启动过程中main功能开始跟踪. 解析命令行參数并保存到ngx_cycle_t结构体中,在ngx_process_options函数中将保存配置文件路径. 调用ngx_add_inheri ...

  2. Nginx安装启动过程报错libpcre.so.1 cannot open shared object file: No such file or directory

    具体报错信息如下: nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: ...

  3. Nginx学习笔记(六) 源码分析&启动过程

    Nginx的启动过程 主要介绍Nginx的启动过程,可以在/core/nginx.c中找到Nginx的主函数main(),那么就从这里开始分析Nginx的启动过程. 涉及到的基本函数 源码: /* * ...

  4. 基于多进程和基于多线程服务器的优缺点及nginx服务器的启动过程

    基于多进程服务器的优点: 1.由操作系统进行调度,运行比较稳定强壮 2.能够方便地通过操作系统进行监控和管理 例如对每个进程的内存变化状况,甚至某个进程处理什么web请求进行监控.同时可以通过给进程发 ...

  5. Nginx源码研究一:NGINX模块启动

    Nginx 是一个轻量级,但是高性能的 HTTP 和 代理 服务器,也是一个 IMAP/POP3/SMTP代理服务器. 它的第一个版本0.1.0是由俄罗斯的工程师Igor Sysoev与2004年10 ...

  6. client和nginx简易交互过程

    # client和nginx简易交互过程- step1:client发起http请求- step2:dns服务器解析域名得到主机ip- step3:默认端口为80,通过ip+port建立tcp/ip链 ...

  7. laravel启动过程简单解析

    :first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1);border-radius:3px ...

  8. 初始nginx(启动运行) 使用nginx做一个简单的静态资源服务器

    第一次接触nginx的时候,那时候公司还是用的一些不知名的小技术,后来公司发展问题,重新招了人,然后接触到nginx,公司 使用nginx用来做代理服务器,所有请求 都先经过nginx服务器,然后交由 ...

  9. linux如何查看nginx是否启动

    Nginx是一个高性能的反向代理服务器,现在一般作为我们网站或其他Web服务的第一层代理,用户在浏览器请求首先经过的就是Nginx服务. 如果Nginx服务没有启动或异常结束,将会影响Web服务的正常 ...

随机推荐

  1. Educational Codeforces Round 46 (Rated for Div. 2) A. Codehorses T-shirts

    Bryce1010模板 http://codeforces.com/problemset/problem/1000/A 题意: 问你将一种类型的衣服转换成另一种的最小次数. #include<b ...

  2. JAVA常用知识总结(二)

    JAVA中的参数传递总结先看两道笔试题: public class Test2 { public static void main (String [] args) { StringBuffer a ...

  3. D. Black Hills golden jewels 二分答案 + 二分判定

    http://codeforces.com/gym/101064/problem/D 题目是给定一个数组,如果两两组合,有C(n, 2)种结果,(找出第一个大于等于第k大的结果) 思路, 二分答案va ...

  4. AJPFX关于java中的方法

    java中的方法和c语言中的函数类似,是新手入门面向对象之前的内容最大的难关如何写方法        1,明确返回值类型        2,明确参数列表 * 修饰符:目前就用 public stati ...

  5. AJPFX关于枚举,泛型详解

    枚举类型是JDK5.0的新特征.Sun引进了一个全新的关键字enum来定义一个枚举类.下面就是一个典型枚举类型的定义:public enum Color{RED,BLUE,BLACK,YELLOW,G ...

  6. position 位置、表单

    一.position    位置 1.只要使用了定位,必须有一个相对的参照物 2.具体定位的那个元素需加position:absolute:(绝对的)   绝对的:就是具体到某一个地方,特别详细的意思 ...

  7. 在git远程仓创建项目之后,提交本地项目的使用方法

    命令介绍 git 用户配置 git config --global user.name "张三" git config --global user.email "zhag ...

  8. spring Existing transaction found for transaction marked with propagation 'never' 解决

    先在申明事务中配置了所有的事务 <!--配置事物传播策略,以及隔离级别--> <tx:advice id="txAdvice" transaction-manag ...

  9. CentOS下JRE环境变量配置

    很多时候,我们需要在CentOS上部署tomcat,从而搭建web服务器,然JDK/JRE环境是前提,这里就记录一下,在后面的时候直接使用. 下载jre-7u80-linux-x64.tar.gz,并 ...

  10. php用面向对象从mysql取数据

    <?php //建立数据库的链接@$_mysqli = new mysqli('localhost','root','123456','dbname');if(mysqli_connect_er ...