Nginx
2010-09-13 09:33:35 阿炯

Nginx ("engine x") 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。Nginx 是由 伊戈尔·西索夫(Igor Sysoev) 为俄罗斯当时访问量第二的Rambler站点开发的,它已经在该站点运行超过多年了。Igor 将源代码以类BSD许可证的形式发布,自Nginx发布以来,已经因为它的稳定性、丰富的功能集、简明的示例配置文件和低系统资源的消耗而闻名了。目前大型网站已经部署了Nginx。

nginx [engine x] is an HTTP and reverse proxy server, as well as a mail proxy server, written by Igor Sysoev. For a long time, it has been running on many heavily loaded Russian sites including Yandex, Mail.Ru, VKontakte, and Rambler.


nginx生态圈的重要开源模块和产品


Nginx是纯C实现的软件,源码质量很高,即使不从事nginx的人也可以将它作为很好的学习软件。作者Igor很早就有支持脚本语言的意图,所以问题就变成了C如何跟脚本语言引擎的结合了。这些主流脚本语言python,php,v8(js),perl,lua都有C的API,考虑到两方面:轻量级和性能,perl成为了当时的nginx首选。甚至他还实现了一个迷你的SSI模块,自定义的脚本功能。但是从现在看,觉得Lua才是和C交互最好的语言,天生为C设计的脚本语言,足够轻量,足够快。章亦春(agentzh)将Lua引入nginx,怎么看都是正确和极具工程实用的选择;估计nginx社区也没料到Lua模块能如此成功。

但是Igor一直有脚本语言的情节,于是在2015年NJS诞生了,也是纯C的JS引擎。Lua天生能跟C交互,但不意味着它能天生跟服务器软件交互。这里最大的问题是语言虚拟机的实现。简单讲,一个请求会有个vm,非常轻量级,不用担心。对nginx的每个请求,Lua的vm虽然做了些处理,但还是可以相互影响,如果你想做的话。但是Lua有GC,这也让这问题变的不是很严重。Igor的NJS是专门为nginx量身定制的JS引擎,还考虑到JS有如此大的用户群体。NJS的每个请求的vm都是相互独立的,不会有任何影响,但是它没有GC。早期GC是列入NJS的计划的,但现在已经变的很遥远了,实现成本太大。这个在 HTTP请求也不是问题,nginx对每个请求都是统一分配和销毁的。如果用户想在配置上增强nginx,比如鉴权,NJS是个很好的选择,这也是它的设计初衷。

Nginx的模块化机制从第一个版本就有了,但是当时Igor并不是为了第三方考虑的,只是为了方便自己的开发。用nginx的人大都会为它的模块化机制感到惊叹,谁都可以不用改nginx源码,只需加入自己的模块,以满足自己的需求。Lua就是最好的例子;但这问题也让Igor很恼火,为什么呢?大量的第三方模块,质量参差不齐,它们严重依赖nginx的api。nginx是20年前的软件,当时的服务器架构跟如今已经不可同日而语。软件需要进化,就要做重构,但是api不能轻易改。关注nginx社区的人知道,Igor亲自设计了另一个跟nginx不同的软件单元,这软件不会再支持模块化了,这是他们的选择。所以从短期看,nginx的模块化让它快速建立了整个生态。从长期看,整个生态也束缚在它的架构上。nginx最大的问题不具备热加载,这种现在主流软件里已经不是问题,反而在它这里变成很棘手的问题,好在很多以Lua为主的应用可以解决这个问题。

Nginx的C实现和模块化机制,让Lua的引入变得顺其自然。虽然也有其它的语言已经支持,但如今证明只有Lua玩转的最好,或者说OpenResty做的最成功。严格来说,OpenResty里的Lua不能叫Lua,是LuaJIT,它以Lua5.1语法为主的另一个分支,而且看着没有跟进官方Lua的计划。Lua5.1以后的版本在语法上有了不少的改进,类似位运算,性能更是如此。对单纯使用Lua而言,非常推荐Lua5.4。

OpenResty让很多开发者大幅提升了开发生产力,并且在它上面衍生了不少开源软件,尤其在API方面,比如Kong和APISIX;也很多公司也有内部的自研尝试。不管多么熟悉nginx源码的开发者,还是只是想用它作为应用服务器,脚本语言都是其中的选择之一。从两方面看nginx:通用功能和业务功能。

通用功能:将它扔进nginx里,如果你能做模块开发,这点尤为重要,这意味着你将享受未来稳定和维护的红利。

业务功能:这个不用多说,维护好业务模块就行了。

从整体看,Lua既封装了nginx的HTTP请求,也提供了独立于请求的功能,比如timer(定时器)和cosocket(跟第三方交互的基础机制)。不管什么模块,也都是基于这两方面进行设计的。如果想学习nginx,对程序员,长期保持自己的竞争力,自研能力是很重要的技能之一。用Lua作为开发的,不妨自己写个框架,如今API框架是非常好的练手对象。

根据 nginx 发布新版的策略,“稳定”指的是功能和更新频率,它与软件质量无关。稳定分支在其生命周期中从不接收新功能,并且通常仅接收一个或两个更新,用于修复严重的错误。另外,稳定版本通常 fork 自最新的 mainline 版本。因此,nginx 1.18.0 fork 自最新的 mainline 版本 1.17.10,它继承了过去一年中 1.17.x 的所有 bugfix 补丁、新增功能和其他变更。

Nginx版本更新录(202x)


官方主页:http://nginx.org/

中文维基:http://wiki.nginx.org/NginxChs

该文章最后由 阿炯 于 2023-03-30 11:52:35 更新,目前是第 2 版。