Chinaunix首页 | 论坛 | 博客
  • 博客访问: 180754
  • 博文数量: 55
  • 博客积分: 207
  • 博客等级: 入伍新兵
  • 技术积分: 320
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-23 19:33
文章分类
文章存档

2012年(53)

2011年(2)

分类:

2012-03-15 15:41:21

原文地址:Nginx源码学习-概览 作者:xueliangfei

源码包解压之后,根目录下有几个子目录和几个文件,最重要的子目录是auto和src,最重要的文件是configure脚本,不同于绝大多数的开源代码,nginx的configure脚本是作者手工编写的,没有使用autoconf之类的工具去自动生成,configure脚本会引用auto目录下面的脚本文件来干活。根据不同的用途,auto目录下面的脚本各司其职,有检查编译器版本的,有检查操作系统版本的,有检查标准库版本的,有检查模块依赖情况的,有关于安装的,有关于初始化的,有关于多线程检查的等等。configure作为一个总驱动,调用这些脚本去生成版本信息头文件、默认被包含的模块的声明代码和Makefile文件,版本信息头文件(ngx_auto_config.h,ngx_auto_headers.h)和默认被包含的模块的声明代码(ngx_modules.c)被放置在新创建的objs目录下。要注意的是,这几个生成的文件和src下面的源代码一样重要,对于理解源码是不可忽略的重要部分。

src是源码存放的目录,configure创建的objs/src目录是用来存放生成的.o文件的,注意区分一下。

src按照功能特性划分为几个部分,对应着是几个不同的子目录。

src/core存放着主干部分、基础数据结构和基础设施的源码,main函数在src/core/nginx.c中,这是分析源码的一个很好的起点。core module的源码 也是Nginx服务的入口

src/event存放着事件驱动模型和相关模块的源码。对自身事件逻辑的封装。

src/http存放着http server和相关模块的源码。nginx作为web/http server运行时的核心模块。

src/mail存放着邮件代理和相关模块的源码。nginx作为imap/pop3/smtp proxy server运行的核心模块。

src/misc存放着C++兼容性测试和google perftools模块的源码。一些utils 定义一些test和profiler的一些外围模块的逻辑。

src/os存放着依赖于操作系统实现的源码,nginx启动过程中最重要的master和workers创建代码就在这个目录下,多少让人觉得有点意外。对各个平台抽象逻辑的封装。
nginx的实现中有非常多的结构体,一般命名为ngx_XXX_t,这些结构体分散在许多头文件中,而在src/core/ngx_core.h中把几乎所有的头文件都集合起来,所有的实现文件都会包含这个ngx_core.h头文件,说nginx的各部分源码耦合厉害就是这个原因,但实际上nginx各个部分之间逻辑上是划分的很清晰的,整体上是一种松散的结构。nginx实现了一些精巧的基础数据结构,例如ngx_string_t,ngx_list_t,ngx_array_t,ngx_pool_t,ngx_buf_t,ngx_queue_t,ngx_rbtree_t,ngx_radix_tree_t等等,还有一些重要的基础设施,比如log,configure file,time等等,这些数据结构和基础设施频繁的被使用在许多地方,这会让人感觉nginx逻辑上的联系比较紧密,但熟悉了这些基础数据结构的实现代码就会感觉到这些数据结构都是清晰分明的,并没有真正的耦合在一起,只是有些多而已,不过nginx中“家酿”的代码也正是它的一个很明显的亮点。

nginx是高度模块化的,可以根据自己的需要定制模块,也可以自己根据一定的标准开发需要的模块,已经定制的模块会在objs/ngx_modules.c中声明,这个文件是由configure生成的。

nginx启动过程中,很重要的一步就是加载和初始化模块,这是在ngx_init_cycle中完成的,ngx_init_cycle会调用模块的hook接口(init_module)对模块初始化,ngx_init_cycle还会调用ngx_open_listening_sockets初始化socket,如果是多进程方式启动,就会调用ngx_master_process_cycle完成最后的启动动作,ngx_master_process_cycle调用ngx_start_worker_processes生成多个工作子进程,ngx_start_worker_processes调用ngx_worker_process_cycle创建工作内容,如果进程有多个子线程,这里也会初始化线程和创建线程工作内容,初始化完成之后,ngx_worker_process_cycle会进入处理循环,调用ngx_process_events_and_timers,该函数调用ngx_process_events监听事件,并把事件投递到事件队列ngx_posted_events中,最终会在ngx_event_thread_process_posted中处理事件。

事件机制是nginx中很关键的一个部分,linux下使用了epool,freebsd下使用了kqueue管理事件。

最后附上Joshua友情提供的源码大图一张,感谢:)
kenbin
 
阅读(1855) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~