Nginx 模块系统:前篇

2024-01-24 11:18
文章标签 模块 系统 nginx 前篇

本文主要是介绍Nginx 模块系统:前篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Nginx 模块系统:前篇

从 Nginx 第一个版本至今已有 17 个年头,在这十余年里,Nginx 一直把持着 Web 服务软件第一梯队的宝座,它背后的丰富的模块系统,犹如蒙古铁骑举着 Nginx 的旗帜,扫荡了全球该领域的大半的市场。

但是我们知道,软件编译是十分耗时的,非常不利于“快速行军”,除了堆硬件外,Nginx 是如何保持相对高速的迭代过程的呢?这背后模块系统和动态模块设计功不可没。

本篇作为第一篇,聊聊书本之外的 Nginx 模块的一些事情,希望能让你对 Nginx 的模块有更立体的认知。

写在前面

2015 年 Nginx 首席工程师 Ruslan Ermilov 的一篇 PPT 分享粗略的提到了 Nginx 模块系统进化过程,以及如何进行动态模块开发。随后在 Nginx 1.19.7 版本中,代码仓库也正式增加了动态模块的编译方式和相关代码。

在一年之后 2016年10月末,一篇来自 Nginx 官方技术博客的文章 “Compiling Third-Party Dynamic Modules for NGINX and NGINX Plus”正式宣布了 Nginx 的新版本 1.9.11 正式支持三方动态模块功能。

自此之后,构建动态模块,再也不单单是社区其他开源的 “Nginx Like” 软件的特权,使用 Nginx 官方发行软件也能够进行更快速的开发、迭代了。

早在 2012 年的秋天,Tengine 团队推出的 1.4.0 版本便支持了该功能,相比较 Nginx 官方团队迟到的 DSO 功能,足足早了 4 年,我们不知道这四年间基于 Nginx 里做 intra 相关的开发者对着屏幕漫长的编译过程,白白消耗了多少时间。但是我们知道在在此期间的阿里云的业务增幅都是三位数的增长,作为阿里巴巴所有业务七层流量入口,提供了大量“应用功能”的 Tengine 功不可没。

但是迟到总比不到强,不是么。

在聊动态模块之前,我们首先要了解它的模块系统。

Nginx 的模块系统

Nginx 的模块系统主要分为“核心功能模块”和“动态模块”,其中动态模块又分为官方模块和三方模块。某种意义上来看,Nginx 的模块算是一种 AOP 思想的应用实践。

Nginx 的内部模块系统

Nginx 能保持高度曝光发展到今天,除了因为有大量三方模块外,这些拥有稳定质量的内部模块同样功不可没。

分别是负责内部通用数据类型、数据对象、内存管理、文件管理、哈希校验、网络通信、锁、网络连接、日志管理、计时器的“核心模块”;负责在不同操作系统,使用不同的事件方案最优解的“事件模块”;负责门面担当、提供高性能 Web 服务的 “HTTP 模块”;提供通用 TCP 代理服务功能的“流模块”;负责邮件服务代理功能的“邮件功能”;以及解决系统差异的“OS模块”。时至今日,这些模块还在保持着比较高的频率进行小步迭代,不断进行优化。

这些模块是 Nginx 的一部分,在一次次编译后,伴随着二进制软件包被分发至千家万户,跨越国界、跨越操作系统,大到绵延数个国家的跨国商业公司、小到你家里的路由器、甚至是电梯里的工控机中都能看到它的身影。

如果 Nginx 缺少了以上任何一个模块、或者模块和 Nginx 主文件版本不一致,软件都将停止工作、或者无法提供高质量的服务能力,可以被称之“亲儿子模块”,都属于标准的静态模块。

前文提到过,软件编译是十分耗时的,文件/功能越多,依赖越多,时间越长。Nginx 最初版本出现时,算上三方模块,Nginx 一共只有三十余模块,但是时至今日,仅仅是官方模块文档中收录的三方模块,就有一百五十多个,还有许多模块散落在各种代码开源平台、个人博客中。

随着 Nginx 版本迭代更新,如果这些模块没有跟上版本迭代而和 Nginx 一起重新构建编译,那么原本的功能便会失效或者引起软件故障。漫长的编译过程,对于模块维护者,尤其是为爱发电的开源作者们来说,无疑是一个不必要的负担。

所以在 Tengine / Openresty 一经推出 Lua 模块之后,便吸引了大量“刚需”用户,在保持差不多 Nginx 性能的水准下,大幅降低了开发的时间成本和学习成本。

于是官方在 2016 年正式推出了支持“三方动态模块”的功能,也就是下文将要提到的外部模块。

Nginx 的外部模块

提到 Nginx 的外部模块,其实分为两类,一类是官方为了保持具备 Nginx 核心功能的软件包小巧、资源占用高效,而特意剥离出来的拥有完整功能,但是不是每个人都需要的模块。另外一类则是完全由社区用户、一些商业公司提供的功能模块。早些时候,官方推出了一个专门用于陈列动态模块的页面,如果你感兴趣可以访问页面进行更直观的了解。

可以说前者同样是属于“亲儿子”阵营,只是“常常住校”不常在家里,后者只是的名誉上的儿子,我们一般称呼为“干儿子”。

这类模块可以单独进行编译,相比较带着 Nginx 这个妈一起构建,时间缩短了至少一个量级,并且可以做到相同 Nginx 版本下,随意组合模块使用,不论是在分发体验,还是使用体验上都有了巨大的“进化”。

在工程效率有了质的提升之后,Nginx 官方推出的软件功能也越来越多,官方在同年年末博客文章中提到的战略产品 Nginx Plus 的主要功能几乎都是由动态模块实现:Brotli、Cookie-Flag、Encrypted-Session、FIPS Status Check、GeoIP、GeoIP2、Headers-More、HTTP Substitutions Filter、Image-Filter、Lua、njs Scripting Language、NGINX ModSecurity WAF、NGINX Developer Kit、OpenTracing、Phusion Passenger Open Source、Perl、Prometheus-njs、RTMP、Set-Misc、SPNEGO、XSLT…

能够动态的加载外部模块好归好,但是也有许多问题和挑战。虽然每个现代操作系统都提供了类似 dlopen 的动态链接库的系统接口,但是玩过应用“动态化”的工程师都知道这里面是个深坑。比如常见的 “Dependency hell” 的问题,类似这个 Bug;一些加载失败的场景检测和对应的处理;或者是五花八门的跨平台编译错误,如果你有耐心,可以在官方问题追踪系统中找到更多的内容。

相比较之前没有动态模块时的状况来看,Nginx 工程师需要承担的 “客服” 解释答疑、以及修复问题相关工作,明显变多了,但是好处也是实打实的:软件生态更开放了、编译效率提升了。F5 公司的股价在五年内也由最初100刀涨到了一度接近翻番,某种程度印证了一句老话“做产品不如做渠道、做渠道不如做平台、做平台不如做生态”。

最后

观察 Nginx 以及一些其他的基于开源软件成长起来的历程,会发现许多好的软件都是相似的,拥有部分开放的规范和接入能力,允许社区进行贡献,然后深入某个或者某些领域功能,不断进行模块功能优化,最终形成拥有相对完整的生态,细分场景又可以打的很深入的局面。

下篇文章中,我们继续聊聊 Nginx 模块的另外一个话题,如何编写和编译一个 Nginx 模块。

–EOF


我们有一个小小的折腾群,里面聚集了一些喜欢折腾的小伙伴。

在不发广告的情况下,我们在里面会一起聊聊软硬件、HomeLab、编程上的一些问题,也会在群里不定期的分享一些技术沙龙的资料。

喜欢折腾的小伙伴欢迎扫码添加好友。(请注明来源和目的,备注实名,否则不会通过审核)

关于折腾群入群的那些事


本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2021年03月05日
统计字数: 4013字
阅读时间: 9分钟阅读
本文链接: https://soulteary.com/2021/03/05/nginx-module-system-part-1.html

这篇关于Nginx 模块系统:前篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/639522

相关文章

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

基于Python实现自动化邮件发送系统的完整指南

《基于Python实现自动化邮件发送系统的完整指南》在现代软件开发和自动化流程中,邮件通知是一个常见且实用的功能,无论是用于发送报告、告警信息还是用户提醒,通过Python实现自动化的邮件发送功能都能... 目录一、前言:二、项目概述三、配置文件 `.env` 解析四、代码结构解析1. 导入模块2. 加载环

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境

Nginx中配置使用非默认80端口进行服务的完整指南

《Nginx中配置使用非默认80端口进行服务的完整指南》在实际生产环境中,我们经常需要将Nginx配置在其他端口上运行,本文将详细介绍如何在Nginx中配置使用非默认端口进行服务,希望对大家有所帮助... 目录一、为什么需要使用非默认端口二、配置Nginx使用非默认端口的基本方法2.1 修改listen指令

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec

Nginx添加内置模块过程

《Nginx添加内置模块过程》文章指导如何检查并添加Nginx的with-http_gzip_static模块:确认该模块未默认安装后,需下载同版本源码重新编译,备份替换原有二进制文件,最后重启服务验... 目录1、查看Nginx已编辑的模块2、Nginx官网查看内置模块3、停止Nginx服务4、Nginx

Linux查询服务器系统版本号的多种方法

《Linux查询服务器系统版本号的多种方法》在Linux系统管理和维护工作中,了解当前操作系统的版本信息是最基础也是最重要的操作之一,系统版本不仅关系到软件兼容性、安全更新策略,还直接影响到故障排查和... 目录一、引言:系统版本查询的重要性二、基础命令解析:cat /etc/Centos-release详

python urllib模块使用操作方法

《pythonurllib模块使用操作方法》Python提供了多个库用于处理URL,常用的有urllib、requests和urlparse(Python3中为urllib.parse),下面是这些... 目录URL 处理库urllib 模块requests 库urlparse 和 urljoin编码和解码

通过配置nginx访问服务器静态资源的过程

《通过配置nginx访问服务器静态资源的过程》文章介绍了图片存储路径设置、Nginx服务器配置及通过http://192.168.206.170:8007/a.png访问图片的方法,涵盖图片管理与服务... 目录1.图片存储路径2.nginx配置3.访问图片方式总结1.图片存储路径2.nginx配置