这是我参与更文挑战的第22天,活动详情查看: 更文挑战
背景
这是Nginx学习笔记汇总的第四篇,Nginx是基于C语言实现的,这里把相关模块化结构整合记录一下.
代码实现
基本数据结构
Nginx的作者为追求极致的高效,实现了很多颇具特色的Nginx风格的数据结构以及公共函数,比如Nginx提供了带长度的字符串,根据编译器选项优化过的字符串拷贝函数ngx_copy等,所以在写Nginx模块时,应该尽量调用Nginx提供的api,尽管有些api只是对 glibc的宏定义
模块化结构
- Nginx的内部结构是由核心部分(Nginx Core)和一系列的功能模块所组成
- Nginx提供了Web服务器的基础功能,同时提供了Web服务反向代理,Email服务反向代理功能
- Nginx core实现了底层的通讯协议,为其他模块和Nginx进程构建了基本的运行时环境,并且构建了其他各模块的协作基础
- 大部分与协议相关的,或应用相关的功能都是在模块中所实现
模块链
- Nginx将各功能模块组织成一条链,当有请求到达时,请求依次经过链上的部分或全部模块,进行处理
- 每个模块实现特定的功能,例如,实现对请求解压缩的模块,实现SSI的模块,实现与上游服务器进行通讯的模块,实现与FastCGI服务进行通讯的模块
- http模块和mail模块比较特殊,他们居于Nginx core和各功能模块的中间,这2个模块在Nginx core之上实现了另外一层抽象,处理与HTTP协议和Email相关协议(SMTP/POP3/IMAP)有关的事件,并且确保这些事件能被以正确的顺序调用其他的一些功能模块
模块的分类
Nginx的模块根据功能可以分为以下几种类型:
- event module: 搭建了独立于操作系统的事件处理机制的框架,及提供了各具体事件的处理,包括ngx_events_module,ngx_event_core_module和ngx_epoll_module等,Nginx具体使用何种事件处理模块,这依赖于具体的操作系统和编译选项
- phase handler: 此类型的模块也被直接称为handler模块,主要负责处理客户端请求并产生待响应内容,比如ngx_http_static_module模块,负责客户端的静态页面请求处理并将对应的磁盘文件准备为响应内容输出
- output filter: 也称为filter模块,主要是负责对输出的内容进行处理,可以对输出进行修改,例如,可以实现对输出的所有html页面增加预定义的footbar一类的工作,或者对输出的图片的URL进行替换之类的工作
- upstream: upstream模块实现反向代理的功能,将真正的请求转发到后端服务器上,并从后端服务器上读取响应,发回客户端,upstream模块是一种特殊的handler,只不过响应内容不是真正由自己产生的,而是从后端服务器上读取的
- load-balancer: 负载均衡模块,实现特定的算法,在众多的后端服务器中,选择一个服务器出来作为某个请求的转发服务器
worker进程
Nginx使用多进程模型来对外提供服务:一个master进程和多个worker进程,master进程负责管理Nginx本身和其他worker进程,所有实际上的业务处理逻辑都在worker进程中完成,worker进程中有一个ngx_worker_process_cycle()函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个Nginx服务被停止
worker进程的一个请求处理流程如下:
- 操作系统提供的机制(例如epoll,kqueue等)产生相关的事件
- 接收和处理这些事件,如是接受到数据,则产生更高层的request对象
- 处理request的header和body
- 产生响应,并发送回客户端
- 完成request的处理
- 重新初始化定时器及其他事件
phase handler
- phase handlers就是某个处理阶段的一个handler
- 每一个阶段都可能包含有若干个handler
- 在处理到某个阶段时,依次调用该阶段的handler对HTTP Request进行处理
- 通常情况下,一个phase handler对这个request进行处理,并产生一些输出
- 通常phase handler是与定义在配置文件中的某个location相关联的
一个phase handler通常执行以下几项任务:
- 获取location配置
- 产生适当的响应
- 发送response header
- 发送response body