想要深入学习nginx,阅读源码一定是非常主要的一环,但nginx源码量毕竟还是不算少,一欠妥心就随意马虎陷入某个细节,迷失落在茫茫码海之中。
如果有一张舆图,让我们开启上帝视角,总览全局,帮助我们快速学习整体框架构造,又能不至于迷失落个中那就再好不过了!
下面选取一些关键部分来一窥神秘的nginx。

nginx主进程启动后,进行一系列的初始化,包括但不限于:
命令行参数解析韶光初始化日志初始化ssl初始化操作系统干系初始化同等性hash表初始化模块编号处理核心初始化其余一个最主要的初始化由ngx_init_cycle()函数完成,该函数环绕nginx中非常核心的一个全局数据构造ngx_cycle_t展开。
该函数完成了几个核心初始化:
配置文件解析创建并监听socket初始化nginx各模块nginx核心模块群nginx是一个模块化设计的软件,精良的架构设计使得nginx可以扩展非常多的模块。
要逐一描述出这些模块显得有些凌乱和事情量巨大,仅选取一些关键核心模块进行了展示:
每个模块有一个支持的命令解析列表,在初始化过程中,主进程将会遍历所有模块的命令列表,进行配置文件中的命令解析,如常常用的ngx_http_proxy_module:
ngx_http_core_module模块:
main函数的末了,根据是否启用多进程模型,分别进入多进程版本的ngx_master_process_cycle和单进程版本的ngx_single_process_cycle()。
以常见的多进程版本为例,进入该函数后,首先设置进程名称为:"master process",随后启动各事情子进程。
启动子进程经由几层封装,终极通过fork启动多个子进程:
除了事情子进程,还启动了缓存管理进程。
之后主进程进入事情循环,周期性更新韶光并检讨各全局标记,根据不同情形给子进程发送不同旗子暗记。
子进程事情循环
子进程启动后,进入ngx_worker_process_cycle,进行一些事情进程的初始化,随后修正进程名称为:"worker process"。
接着进入事情循环函数ngx_process_events_and_timers,在该函数中紧张卖力:
竞争互斥锁,拿到锁的进程才能实行accept接管新的连接,以此在多进程之间办理惊群效应通过epoll异步IO模型处理网络IO事宜,包括新的连接事宜和已建立连接发生的读写事宜处理定时器行列步队中到期的定时器事宜,定时器通过红黑树的办法存储HTTP要求预处理当连接有数据产生时,事情线程读取socket中到来的数据,并根据HTTP协议格式进行解析,终极封装成ngx_request_t要求工具,提交处理。
HTTP要求处理的11个阶段
在nginx中各HTTP模块因此挂载的形式串接而成,以流水线事情模式进行HTTP要求的处理,nginx将一个HTTP要求的处理划分为11个阶段。
typedef enum { NGX_HTTP_POST_READ_PHASE = 0, NGX_HTTP_SERVER_REWRITE_PHASE, NGX_HTTP_FIND_CONFIG_PHASE, NGX_HTTP_REWRITE_PHASE, NGX_HTTP_POST_REWRITE_PHASE, NGX_HTTP_PREACCESS_PHASE, NGX_HTTP_ACCESS_PHASE, NGX_HTTP_POST_ACCESS_PHASE, NGX_HTTP_PRECONTENT_PHASE, NGX_HTTP_CONTENT_PHASE, NGX_HTTP_LOG_PHASE} ngx_http_phases;
每阶段(部分阶段保留,不许可挂载)许可多个模块挂载,一个模块也可以挂载到多个阶段。因此,初次完成挂载的存储构造是一个二维数组的形式。
不过在初始化过程中,ngx_http_init_phase_handlers函数将该二维数组转换成了一维数组。下图是nginx中各模块挂载情形:
全景图
末了,再来看一看全貌:
总结
nginx不仅是一款精良的高性能web做事器,对付C/C++技能栈的同学来说,还是一个很好的学习工具,其良好的架构设计,幽美的代码风格和经典的编程技法无一不值得细细品来。
不过限于笔者水平和韶光有限,虽然号称全景图,但依然无法覆盖到nginx的方方面面,欢迎读者朋友留言互换,让此图日渐完善,感激大家。