php万能表单源码_全网第一张源码,分析全景图,揭秘Nginx

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

78dc6791b68d1abf3ba4869961578011.png

想要深入学习nginx,阅读源码一定是非常重要的一环,但nginx源码量毕竟还是不算少,一不小心就容易陷入某个细节,迷失在茫茫码海之中。

如果有一张地图,让我们开启上帝视角,总览全局,帮助我们快速学习整体框架结构,又能不至于迷失其中那就再好不过了!

7c397ceb794ea566dc8ceb4fb0100885.png

下面选取一些关键部分来一窥神秘的nginx。

主进程启动

nginx主进程启动后,进行一系列的初始化,包括但不限于:

  • 命令行参数解析
  • 时间初始化
  • 日志初始化
  • ssl初始化
  • 操作系统相关初始化
  • 一致性hash表初始化
  • 模块编号处理
4e84a920a4524f67d97e53f67cef700a.png

核心初始化

另外一个最重要的初始化由ngx_init_cycle()函数完成,该函数围绕nginx中非常核心的一个全局数据结构ngx_cycle_t展开。

807fb6374abc9b68e5e67ec93a29a4f2.png

该函数完成了几个核心初始化:

  • 配置文件解析
  • 创建并监听socket
  • 初始化nginx各模块
3a58886d1e45ac90b0f1f5b0c04fbad5.png

nginx核心模块群

nginx是一个模块化设计的软件,优秀的架构设计使得nginx可以扩展非常多的模块。

b3e7bf9d0bdc843cbe41638e7680d0d1.png

要一一描绘出这些模块显得有些杂乱和工作量巨大,仅选取一些关键核心模块进行了展示:

f4d69f121b130c14a8aef310ae4f867f.png

每个模块有一个支持的命令解析列表,在初始化过程中,主进程将会遍历所有模块的命令列表,进行配置文件中的命令解析,如经常用的ngx_http_proxy_module:

fa67b977f4c52ab66d9ac215a6622ea3.png

ngx_http_core_module模块:

d328f9f366441f96d363ab14e0a28404.png

main函数的最后,根据是否启用多进程模型,分别进入多进程版本的ngx_master_process_cycle和单进程版本的ngx_single_process_cycle()。

以常见的多进程版本为例,进入该函数后,首先设置进程名称为:"master process",随后启动各工作子进程。

启动子进程经过几层封装,最终通过fork启动多个子进程:

2c883180df202339513e23062f7973d8.png

除了工作子进程,还启动了缓存管理进程。

之后主进程进入工作循环,周期性更新时间并检查各全局标记,根据不同情况给子进程发送不同信号。

95d7e1f00a493b1eb6d1dddef698795c.png

子进程工作循环

子进程启动后,进入ngx_worker_process_cycle,进行一些工作进程的初始化,随后修改进程名称为:"worker process"

接着进入工作循环函数ngx_process_events_and_timers,在该函数中主要负责:

  • 竞争互斥锁,拿到锁的进程才能执行accept接受新的连接,以此在多进程之间解决惊群效应
  • 通过epoll异步IO模型处理网络IO事件,包括新的连接事件和已建立连接发生的读写事件
  • 处理定时器队列中到期的定时器事件,定时器通过红黑树的方式存储
c4e55326febd3893bdd6709d23f64214.png

HTTP请求预处理

当连接有数据产生时,工作线程读取socket中到来的数据,并根据HTTP协议格式进行解析,最终封装成ngx_request_t请求对象,提交处理。

74a4846169ca0550d6db902609613aea.png

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中各模块挂载情况:

902ae0ab516395a142882d2224365cbe.png

全景图

最后,再来看一看全貌:

7c397ceb794ea566dc8ceb4fb0100885.png

总结

nginx不仅是一款优秀的高性能web服务器,对于C/C++技术栈的同学来说,还是一个很好的学习对象,其良好的架构设计,优美的代码风格和经典的编程技法无一不值得细细品来。

不过限于笔者水平和时间有限,虽然号称全景图,但依然无法覆盖到nginx的方方面面,欢迎读者朋友留言交流,让此图日渐完善,谢谢大家。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值