博客 | NGINX

使用 njs 0.7.7 让你的 NGINX 配置更加模块化和可重用

NGINX-F5-horiz-black-type-RGB 的一部分
Prabhat Dixit 缩略图
帕拉巴特·迪克西特
2022 年 10 月 20 日发布


自从在2015(原名 nginScript)并于 2017 年全面推出<.htmla>,我们一直在稳步地在数十个版本更新中持续添加新功能并改进我们的实现。 通常我们会等待 NGINX Plus 发布后再讨论新 NGINX JavaScript 版本中的功能,但我们对 0.7.7 版本感到非常兴奋,所以这次我们迫不及待了!

njs 0.7.7 中的重大增强功能有助于使您的 NGINX 配置更加模块化、有条理且可重用:

要了解有关 njs 的更多信息并查看我们提供示例代码的用例列表,请阅读我们博客上的使用 NGINX JavaScript 模块为每个请求发挥 JavaScript 的强大功能和便利性

有关 njs 0.7.7 中所有新功能和错误修复的完整列表,请参阅更改文档。

在本地上下文中声明 JavaScript 代码和变量

在以前的 njs 版本中,您必须导入 JavaScript 代码并在顶级http上下文中声明相关变量(使用js_importjs_pathjs_setjs_var指令),相当于在主文件顶部声明全局变量。 但实际调用 JavaScript 函数和变量的指令出现在子上下文中 - 例如,HTTP location{}块中的js_content指令和 Stream server{}块中的js_access指令。 这会产生两个问题:

  1. 对于阅读配置的人来说, http上下文中的声明本质上是噪音,因为没有迹象表明相关代码和变量实际在哪里使用。
  2. 在子上下文中,代码和变量的导入和声明位置并不明显。 尽管我们建议仅在主配置文件( nginx.conf )中包含http{}stream{}块,并使用include指令从/etc/nginx/conf.d/etc/nginx/stream.d目录中读取较小的特定于功能的配置文件,但 NGINX 配置非常灵活 - 您可以在多个文件中包含http{}stream{}块。 在多人处理 NGINX 配置且可能并不总是遵循既定惯例的环境中,这种情况尤其成问题。

在 njs 0.7.7 及更高版本中,您可以导入代码并在使用变量的上下文中声明变量:

将针对特定用例的所有 njs 配置放在一个文件中也能使您的代码更加模块化和可移植。

举个例子,在以前的 njs 版本中,当你添加一个新脚本时,你必须同时更改nginx.conf (添加js_import以及可能的js_pathjs_setjs_var )和调用 JavaScript 函数的文件(此处为jscode_local.conf )。

在 njs 0.7.7 及更高版本中,与 util 功能相关的所有配置都在一个文件jscode_integrated.conf中:

根据执行上下文修改行为

njs 0.7.7 中的几个新功能使您能够根据 JavaScript 代码的执行上下文(处理阶段)修改其行为。

HTTP r.internal属性

HTTP r.internal属性是一个布尔标志,对于内部请求(由包含内部指令的location{}块处理)设置为“true”。 当脚本使用可以在内部和非内部上下文中调用的通用事件处理程序时,您可以使用r.internal标志来分叉逻辑。

以下归类为内部请求:

改进的s.send()流方法

在早期的 njs 版本中,Stream s.send()方法是上下文相关的,因为它发送数据的方向由调用该方法的回调的位置(上游或下游)决定。 这对于同步回调很有效 - s.send()最初是为此设计的 - 但对于异步函数如ngx.fetch()则失败。

在 njs 0.7.7 及更高版本中,方向存储在单独的内部标志中,然后s.send()可以使用该标志。

使用新的fs.FileHandle()对象实现更高效的文件操作

文件系统模块( fs )实现对文件的操作。 fs模块中的新FileHandle对象是数字文件描述符的对象包装器。 FileHandle对象的实例由fs.promises.open()方法创建。

使用FileHandle对象获取文件描述符,该描述符可进一步用于:

  • 对文件执行read()write()等函数
  • 打开文件并在指定位置执行读写操作,而无需读取整个文件

FileHandle的以下属性已被实现(有关每个属性的必需和可选参数的信息,请参阅文档):

  • 文件句柄
  • 文件句柄.read()
  • 文件句柄.stat()
  • 文件句柄.write()
  • 文件句柄.write()
  • 文件句柄.close()

这些方法已更新为支持FileHandle (有关每种方法的参数的信息,请参阅链接的文档):

使用 njs 增强你的配置

通过 njs 0.7.7,我们让您的团队可以更轻松地处理和共享 njs 代码。 njs 指令的扩展上下文使得使用自定义 JavaScript 代码增强 NGINX 配置变得更加直接。 您可以首先转向 API 网关、反向代理或 Web 服务器 - 它们不仅仅是另一个中间件或边缘组件。 您可以通过 JavaScript、 TypeScript或第三方节点模块使其成为应用的一部分,而无需在堆栈中添加其他组件。 您所需要的只是 NGINX!

有疑问吗? 加入NGINX 社区 Slack并查看#njs-code-review频道以了解更多信息、提出问题并获取有关您的 njs 代码的反馈。


“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”