Chinaunix首页 | 论坛 | 博客
  • 博客访问: 224305
  • 博文数量: 41
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 407
  • 用 户 组: 普通用户
  • 注册时间: 2013-06-27 13:42
文章分类

全部博文(41)

文章存档

2016年(1)

2015年(18)

2014年(22)

我的朋友

分类: LINUX

2014-08-29 16:30:01

    根据自己的需要目前只分析了一部分,这个我认为是很关键,还有很多需要完善的地方,但是整个框架已经出来了。后面几天会逐步补全

流程(从main函数开始):
    -- 对参数选项进行处理
    -- 初始化时间和日志等
    -- 给init_cycle创建内存池
    -- ngx_save_argv将命令行参数保存在全局变量中,算是备份存储,方便master进程做热代码替换之用
    -- ngx_os_init完成操作系统的一些信息获取,如内存页面大小、系统限制资源等信息;将所有的这些资源都保存在对应的全局变量中。
    -- ngx_crc32_table_init初始化一个做循环冗余校验的表,后续的循环冗余校验将采用高效的查表法
    -- ngx_add_inherited_sockets通过环境变量NGINX完成socket的继承,继承来的socket将会放到init_cycle的listening数组中。在NGINX环境变量中,每个socket中间用冒号或分号隔开。完成继承同时设置全局变量ngx_inherited为1。
    -- module的数量并设置每个module的index
    -- ngx_init_cycle(启动时,初始化cycle结构体)
        >> 对时区与时间进行一次更新操作
        >> 分配一个大小为NGX_CYCLE_POOL_SIZE的内存池
        >> 在内存池上分配一个ngx_cycle_t对象
        >> 初始化一个链表,nginx使用链表来维护需要打开的文件以及共享内存,每个打开的文件都会放到cycle中的open_files链表中,每个共享内存段都会放到shared_memory链表中。
        >> 初始化listening数组,这个数组将用于存储监听套接字
        >> conf_ctx初始化了一段内存空间(可以看成是一个普通的数组),这段空间能够存储ngx_max_module(main函数中设置index时统计的所有模块的总数)个void *指针。
        >> 调用所有核心模块(NGX_CORE_MODULE)的create_conf方法生成存放配置项的结构体,然后这个配置结构存储空间的地址保存到conf_ctx数组的对应单元处,寻找正确的对应单元就是通过每个模块的index字段
        >> 调用ngx_conf_parse, 读取配置文件进行解析,并进行相关的设置(包括设置监听端口的处理方法),解析配置文件的时候,将会完成每个指令的set回调,这个set回调函数一般都是讲配置数据填写到配置结构中。
        >> 调用所有NGX_CORE_MODULE类型模块的init_conf回调函数,完成配置结构的初始化工作。
        >> 循环遍历cycle的open_files链表,如果存储了文件名就打开对应的文件。填写文件名数据就是在解析配置文件的时候完成的。除此之外很多数据的初始化都是在解析配置文件的时候完成。执行了打开文件操作之后,open_files链表就不光保存了文件名了,还保存了文件描述符等信息。
        >> 循环遍历cycle的shared_memory,初始化各个共享内存段
        >> 遍历listening数组,打开所有的监听套接口,同时设置一些socket选项以及文件描述符属性,如非阻塞等。
        >> 调用所有模块的init_module(目前只有ngx_event_core_module设置了该回调函数)
            ++ 首先取得ngx_events_module在conf_ctx中存储的配置结构体数组的地址
            ++ 取得ngx_event_core_module模块的配置结构
            ++ 取得ngx_core_module模块的配置结构
            ++ 从ngx_core_module模块的配置结构中获取timer_resoluting指令的配置参数
            ++ 创建共享内存实现锁等工作
            ++
    -- ngx_init_signals注册一堆信号处理程序
    -- 如果需要daemon,调用ngx_daemon实现守护进程

    -- 完成了初始化工作,调用ngx_signal_process_cycle或ngx_master_process_cycle
          >> 调用所有模块的init process方法(目前只看到ngx_event_core_module模块设置了这个方法)
              -- ngx_event_core_module中的ngx_event_process_init方法
                >> 获取相应模块的配置结构(ngx_core_module与ngx_event_core_module)
                >> ngx_event_timer_init,初始化计时器,此处将会创建一颗红黑树,来维护计时器
                >> 遍历模块数组(非NGX_EVENT_MODULE和非use配置指令指定的模块都会跳过),调用具体时间模块的init函数
                >> 针对use设置的event模块调用actions.init方法(对于epoll,调用的是ngx_epoll_init方法)
                    ++ epoll模块中的ngx_epoll_init方法会将全局变量ngx_events_actions设置为epoll模块中的actions
                >> 创建一个connections数组,维护所有的connections,本过程已经狮子啊worker进程中了,所以是每个worker都有自己的connection数组
                >> 分配connection_n个空间给read_events和write_events,并进行初始化    
                >> 把connection和read_event、write_event联系起来,每个connection都指向一个read_event和write_event
                >> 循环设置listening sockets(包括设置对应connection的read为ngx_event_accept
                    ++ 获取一个空闲的connection,并设置其fd为listening fd
          ++ 设置connection->read的handler为ngx_event_accept(该函数会调用ngx_listening_t的handler,对于http框架会调用ngx_http_init_connection)
                    ++ 将listening fd加入epoll监听,其中事件中的data的ptr设置为对应的connection,以便回调。
                    ++ listening fd的回调是调用ngx_event_accept
                        ~~ accept
                        ~~ 获取新的connection
                        ~~ 设置connection的回调函数
                        ~~ 调用ngx_listening_t的handler(ngx_http_init_connection)
          >> 进入死循环,处理事件
              -- ngx_process_events_and_timers
                  -- 调用ngx_process_events(实际上就是ngx_events_actions的process_events函数,如果是epoll,那么调用的就是ngx_epoll_process_events函数)
        
阅读(1417) | 评论(0) | 转发(0) |
1

上一篇:非阻塞式IO

下一篇:upstream机制

给主人留下些什么吧!~~