BLOG | NGINX

使用 njs 0.7.7 提高 NGINX 配置的模块化程度和可复用性

NGINX-Part-of-F5-horiz-black-type-RGB
Prabhat Dixit 缩略图
Prabhat Dixit
Published October 20, 2022

2015 年推出 NGINX JavaScript 模块 (njs)(原名 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 或 stream 上下文中声明相关变量(使用 js_importjs_pathjs_setjs_var 指令),这相当于在主文件顶部声明全局变量。但实际调用 JavaScript 函数和变量的指令却出现在子上下文中 — 例如,http location{} 块中的 js_content 指令,stream server{} 块中的 js_access 指令。这会产生两个问题:

  1. 对于浏览配置的人员而言,httpstream 上下文中的声明基本上是噪声,因为没有指明实际使用相关代码和变量的位置。
  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 代码的上下文(处理阶段)修改其行为。

The HTTP r.internal 属性

HTTP r.internal 属性是一个布尔标志,针对内部请求(由添加了 internal 指令的 location{} 块进行处理)设置为 “true”。当一个脚本使用能够在内部和非内部上下文中调用的一般事件处理程序时,您可使用 r.internal 标志来派生 (fork) 逻辑。

以下属于内部请求:

改进的 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 的以下属性(有关每个属性的必选和可选参数的信息,请参阅文档):

  • filehandle.fd
  • filehandle.read()
  • filehandle.stat()
  • filehandle.write()
  • filehandle.write()
  • filehandle.close()

以下方法已经更新,可支持 FileHandle(请参阅链接文档,获取有关每个方法的参数信息):

 

使用 njs 增强您的配置

借助 njs 0.7.7,您的团队能够更轻松地操作和共享 njs 代码。njs 指令的扩展上下文让使用自定义 JavaScript 代码来增强 NGINX 配置变得更加简单。

您可以将其用于 API网关、反向代理或 Web 服务器 — 不只是中间件或边缘组件。您可以通过 JavaScript、TypeScript 或第三方节点模块让其成为您应用的一部分,而无需在堆栈中添加其他组件。只需使用 NGINX 即可!

有问题?请添加“小 N 助手(微信号:nginxoss)”加入到我们的官方微信群,以了解更多信息、提出问题并获得有关您 njs 代码的反馈。


"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."