Nginx 模块和指令的区别:http/server/location 不是模块,是指令

这篇文章,主要是想搞明白,

在 Nginx 中,「模块 Module」和「指令 Command」是什么关系。

这是个很容易混淆的概念。

很多人以为 http、server、location 是模块,其实不是的。

在 Nginx 中,

模块,是功能单元,从源码层面来看,通常一个 .c 源代码文件对应一个功能模块。

指令,是配置文件中的关键字,由模块注册提供。

下次再看到 Nginx 的配置文件时,记住:

哪些才是模块

Nginx 的模块都是 C 语言写的,在 src/ 目录下。

其实有很多的模块。

这些模块,可以分类。

在 ngx_module_s 结构体里面,有一个 type 字段,也就是模块类型。

我使用命令分析了一下,一共可分成 6 大类。

不管具体的模块名字有多花,最终都必须归属到这 6 个 type 之一。

从源码目录也能看到这种分类,只有 NGX_CONF_MODULE 没有独立目录。

为什么呢?因为它不是功能模块,而是配置系统,只在启动时工作: Nginx 启动、解析配置、初始化完成、CONF 模块任务就完成了,所以没必要单独建目录。

另外,misc/ 和 os/ 不是模块目录,是为了适配不同操作系统,跨平台兼容的工具代码。

回到模块体系,Nginx 的设计很严格,所有功能模块都必须归属于这 6 大类型之一。

但是 HTTP、Stream 就已经挺复杂的,它是怎么靠 6 个类型就搞得这么多功能点的呢?

其实主要不是靠增加新类型扩展,而是在单一类型的内部,通过 hook 和请求处理阶段机制,把复杂功能拆分成多个小模块,共同协作完成。

我通过查看编译后生成的 objs/ngx_modules.c 文件,整理出了完整的模块列表。

下面是我的配置命令:

我没有带 --with-http_v3_module,因为它需要支持 QUIC 的 OpenSSL,但系统默认的 OpenSSL 不支持 QUIC,搞起来比较麻烦。

./configure 执行后会自动生成 objs/ngx_modules.c,这个文件定义了 ngx_module_names[] 数组,里面是所有将被编译进 nginx 的模块列表。

我觉得还是全部列出来,完整的感受一下比较好,下图中一共有 110 个模块。

源码里有这么多模块,但不是所有模块都会被编译进去。

编译时需要通过 --with-xxx 显式启用某些模块,否则最终的 nginx 不支持这些功能。

比如,stream 模块默认就是不启用的,需要在编译时显式指定 --with-stream 才会被编译进 nginx。

如果编译时不带 --with-stream,最终的 nginx 就不支持 stream 功能(TCP/UDP 代理)。

总结来看:Nginx 有 6 大模块类型,各司其职。

HTTP、Stream、Mail 负责协议处理,Event 负责并发,Core 提供基础功能,Conf 在启动时解析配置并关联各模块。

一个模块可以注册多个指令

在 Nginx 中,指令用 ngx_command_t 结构体表示。

下面是 ngx_http_core_module 模块注册指令的代码。

一个模块可以注册多个指令,每个指令都有自己的名称和处理函数。

这个处理函数,会在配置解析阶段被调用。

这里注册的 listen 指令,对应的处理函数是 ngx_http_core_listen。

指令的处理函数什么时候被调用?

简单来说,Nginx 启动或 reload 配置时,解析到这个指令就会调用。

具体的流程是:

  1. Nginx 启动或执行 nginx -s reload;
  2. 读取 nginx.conf,逐行解析;
  3. 遇到 listen 80; 这样的指令;
  4. 查找 listen 对应的 ngx_command_t 结构;
  5. 调用它的 set 回调函数,也就是 ngx_http_core_listen;
  6. 解析参数(80、ssl、backlog 等),保存到配置结构体;

比如我们的线上环境,是这样配置的,

这些参数(ssl、http2、reuseport、backlog 等)都是在 ngx_http_core_listen 函数中解析的。

一个指令可以有多个参数,处理函数会逐一解析并保存到配置结构体中。

注意区分:配置解析 vs 请求处理

两者完全不同阶段,容易混淆。

但搞明白了,就能看清 Nginx 的运行机制,

配置解析只在启动时做一次,而请求处理是持续进行的。

1、指令的处理函数

在启动或reload时调用,用于解析配置。

比如:ngx_http_core_listen 解析 listen 指令的参数。

2、请求处理函数

在运行时调用,用于处理每个 HTTP 请求。

比如:proxy_pass 指令在启动时调用 ngx_http_proxy_pass 解析配置,在请求到来时调用 ngx_http_proxy_handler 转发请求。

总结

Nginx 中「模块」和「指令」的关系:

模块

  • 功能单元,通常对应一个 .c 源文件;
  • 分为 6 大类型:CORE、CONF、EVENT、HTTP、MAIL、STREAM;
  • 源码中有上百个模块,但有些是编译时需通过 --with-xxx 选项启用的;

指令

  • 配置文件中的关键字(如 listen、proxy_pass);
  • 由模块注册提供,一个模块可注册多个指令;
  • 每个指令有专属的处理函数,用于解析配置参数;
  • 指令的处理函数在启动/reload 时调用,和请求处理函数完全不同;

下次你看配置文件时,记住:http/server/location不是模块。

当你想知道有哪些模块时,去看看 objs/ngx_modules.c...

理解这些基础,才能更好看懂 Nginx 的架构设计。

相关推荐
高木木的博客5 小时前
数字架构智能化测试平台(1)--总纲
人工智能·python·nginx·架构
徐子元竟然被占了!!6 小时前
Nginx
运维·nginx
图图玩ai7 小时前
SSH 命令管理工具怎么选?从命令收藏到批量执行一次讲清
linux·nginx·docker·ai·程序员·ssh·可视化·gmssh·批量命令执行
CXH7288 小时前
nginx——https
运维·nginx·https
Lentou10 小时前
nginx反向代理
运维·nginx
遇见火星10 小时前
linux设置开启启动服务
linux·运维·服务器·nginx
咸鱼翻身小阿橙11 小时前
QT P4
数据库·qt·nginx
o丁二黄o13 小时前
若依部署Nginx和Tomcat
运维·nginx·tomcat
一个public的class14 小时前
前后端 + Nginx + Gateway + K8s 全链路架构图解
前端·后端·nginx·kubernetes·gateway
bukeyiwanshui15 小时前
20260420 Nginx 服务器
运维·服务器·nginx