震撼!全网第一张源码分析全景图揭秘Nginx

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介:

震撼!全网第一张源码分析全景图揭秘Nginx

不管是C/C++技术栈,还是PHP,Java技术栈,从事后端开发的朋友对nginx一定不会陌生。

想要深入学习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的方方面面,欢迎读者朋友留言交流,让此图日渐完善,谢谢大家。

获取完整高清大图,可在公众号里回复“nginx”自动获取。

原文地址https://www.cnblogs.com/xuanyuan/p/12710715.html

相关文章
|
27天前
|
应用服务中间件 BI nginx
Nginx的location配置详解
【10月更文挑战第16天】Nginx的location配置详解
|
1月前
|
缓存 负载均衡 安全
Nginx常用基本配置总结:从入门到实战的全方位指南
Nginx常用基本配置总结:从入门到实战的全方位指南
256 0
|
1月前
|
应用服务中间件 Linux nginx
Jetson 环境安装(四):jetson nano配置ffmpeg和nginx(亲测)之编译错误汇总
这篇文章是关于在Jetson Nano上配置FFmpeg和Nginx时遇到的编译错误及其解决方案的汇总。
89 4
|
7天前
|
存储 负载均衡 中间件
Nginx反向代理配置详解,图文全面总结,建议收藏
Nginx 是大型架构必备中间件,也是大厂喜欢考察的内容,必知必会。本篇全面详解 Nginx 反向代理及配置,建议收藏。
Nginx反向代理配置详解,图文全面总结,建议收藏
|
19天前
|
应用服务中间件 API nginx
nginx配置反向代理404问题
【10月更文挑战第18天】本文介绍了使用Nginx进行反向代理的配置方法,解决了404错误、跨域问题和302重定向问题。关键配置包括代理路径、请求头设置、跨域头添加以及端口转发设置。通过调整`proxy_set_header`和添加必要的HTTP头,实现了稳定的服务代理和跨域访问。
nginx配置反向代理404问题
|
1月前
|
编解码 Ubuntu 应用服务中间件
Jetson 环境安装(三):jetson nano配置ffmpeg和nginx(亲测)
本文介绍了在NVIDIA Jetson Nano上配置FFmpeg和Nginx的步骤,包括安装、配置和自启动设置。
137 1
Jetson 环境安装(三):jetson nano配置ffmpeg和nginx(亲测)
|
24天前
|
缓存 负载均衡 应用服务中间件
Nginx配置
【10月更文挑战第22天】在实际配置 Nginx 时,需要根据具体的需求和环境进行调整和优化。同时,还需要注意配置文件的语法正确性和安全性。
40 7
|
1月前
|
前端开发 JavaScript 应用服务中间件
终极 Nginx 配置指南
本文介绍了Nginx的基本配置及其优化方法。首先,通过删除注释简化了Nginx的默认配置文件,使其更易于理解。接着,文章将Nginx配置文件分为全局块、events块和http块三部分进行详细解释。此外,还提供了如何快速上线网站、解决前端history模式404问题、配置反向代理、开启gzip压缩、设置维护页面、在同一IP上部署多个网站以及实现动静分离的具体配置示例。最后,附上了Nginx的基础命令,包括安装、启动、重启和关闭等操作。
|
1月前
|
负载均衡 应用服务中间件 nginx
Nginx的6大负载均衡策略及权重轮询手写配置
【10月更文挑战第9天】 Nginx是一款高性能的HTTP服务器和反向代理服务器,它在处理大量并发请求时表现出色。Nginx的负载均衡功能可以将请求分发到多个服务器,提高网站的吞吐量和可靠性。以下是Nginx支持的6大负载均衡策略:
148 7
|
1月前
|
缓存 前端开发 应用服务中间件
CORS跨域+Nginx配置、Apache配置
CORS跨域+Nginx配置、Apache配置
140 7