BLOG | NGINX

隆重推出 NGINX Plus R27

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

很高兴宣布推出 NGINX Plus 版本 27 (R27)。NGINX Plus 基于 NGINX 开源版构建而成,是唯一一款将软件 Web 服务器、负载均衡器、反向代理、内容缓存和 API 网关集于一身的多合一产品。

NGINX Plus R27 的全新增强特性包括:

  • 为健康检查引入 keepalive 连接 –– 在之前的版本中,NGINX Plus 每次进行健康检查都会建立新连接。HTTP health_check 指令的新参数 keepalive_time 可为健康检查建立 keepalive 连接,并设置其连接时长。建立新连接的计算成本很高,当存在大量上游服务器时,复用连接可大大降低 CPU 使用率。
  • 支持 Kernel TLS –– NGINX Plus 现可在三种操作系统上支持 Kernel TLS (kTLS):FreeBSD 13、RHEL 9.0+ 和 Ubuntu 22.04 LTS。
  • 为上游服务器和虚拟服务器生成 TLS 指标 –– 除之前版本生成的全局统计数据以外,在启用 HTTPS 代理的情况下,NGINX Plus 现在还能够为每个上游服务器和虚拟服务器生成 TLS 统计数据。兼具来自客户端和服务器端的指标有助于解决 TLS 握手方面的问题。
  • 自定义 JWT 验证失败时的错误代码 –– NGINX Plus R25 和 R26 支持自定义 JWT 验证检查,但验证失败时返回的错误代码始终是 401 (Unauthorized)。NGINX Plus R27 为 auth_jwt_require 指令引入了 error 参数,可支持将每次检查时的错误代码设置为 401403 (Forbidden),以更有效地区分认证和授权错误。
  • NGINX JavaScript 和 Prometheus-njs 模块的增强功能 –– NGINX JavaScript 模块添加了新指令和新对象,可分别用来微调 ngx.fetch 函数的行为并以十六进制数的形式报告 njs 版本。Prometheus-njs 模块现在可将更多 NGINX Plus 指标转换为 Prometheus 数据格式:codes 字段(报告上游服务器和虚拟服务器各个 HTTP 状态代码的数量)以及 Limit Connections 和 Limit Requests 模块生成的指标。

此外,该版本还将 NGINX Plus API 的版本号更新为 (8),以及在 Linux 内核中使用 EPOLLEXCLUSIVE 模式时能够更均匀地分配连接。

 

重要行为变更

注意: 如果您不是从 NGINX Plus R26 升级至 NGINX Plus R27,请务必查看公告博客中的“重要行为变更” 部分,了解您当前版本和最新版本之间所有版本的变更记录。

全新操作系统支持:

  • Alpine Linux 3.16
  • RHEL 9.0+(首次发布后添加到了 NGINX Plus R26 中)
  • Ubuntu 22.04 LTS(首次发布后添加到了 NGINX Plus R26 中)

已弃用的旧版操作系统和架构:

  • Alpine 3.12,已于 2022 年 5 月 1 日停服
  • CentOS 8.1+,已于 2021 年 12 月 31 日停服(因停服日期不同,RHEL 8.1+ 仍提供支持)
  • Power 8 架构(ppc64le;影响 CentOS 和 RHEL)

以下旧版操作系统和架构已弃用并计划在 NGINX Plus R28 中移除:

  • Debian 10,将于 2022 年 8 月停服

 

新增特性详情

为健康检查引入 keepalive 连接

在 NGINX Plus 和上游服务器之间建立 Keepalive 连接可显著改善反向代理和负载均衡场景下的性能。特别是对于 HTTPS 代理而言,每个完整的 TLS 握手都需要新建连接,会消耗大量计算资源并造成资源紧张,在上游服务器众多的生产环境中尤为如此。

在以前的版本中,NGINX Plus 并不使用 keepalive 连接进行健康检查,而是为每次健康检查都建立新连接。NGINX Plus R27 为 HTTP 健康检查引入了 keepalive 连接。health_check 指令的新参数 keepalive_time 可设置每个 keepalive 连接时长,然后建立新连接。我们的测试表明,对于 HTTPS 代理,keepalive 连接可将 NGINX Plus 服务器健康检查时的 CPU 使用率降低 10 到 20 倍。此外,它们还减少了上游服务器占用的 CPU 资源。

以下示例是连接时常为 60 秒的 keepalive 连接。interval 参数设置的健康检查频率为 1 秒,因此 NGINX Plus 每 60 次健康检查只会产生一次 TLS 握手和连接建立开销。

支持 Kernel TLS

传输层安全协议 (TLS) 是互联网数据加密领域事实上的标准协议。令人遗憾的是,数据保护也会增加延迟。在内核中实现 TLS (kTLS) 可显著减少在用户空间与内核之间复制操作,从而提升提供静态内容服务时的性能。

通过结合使用 kTLS 与 sendfile() 系统调用,可直接在内核空间加密数据,然后再传递到网络堆栈进行传输,而不是将数据复制到用户空间,使用 TLS 库加密数据,然后再复制回内核空间进行传输。kTLS 还支持将 TLS 处理卸载到硬件,包括将 TLS 对称加密处理卸载到网络设备。

支持 kTLS 需满足以下三个要求:

  1. 操作系统内核支持 kTLS
  2. 发行版操作系统提供支持 kTLS 的 OpenSSL 3.0+ 加密库
  3. NGINX Plus(或 NGINX 开源版)使用 OpenSSL 3.0+ 加密库构建

2021 年 10 月,我们为满足要求 1 和 2 的平台上的 NGINX 开源版 1.21.4 添加了 kTLS 支持。现在,我们又为下列平台上的 NGINX Plus 添加了 kTLS 支持:

  • FreeBSD 13(NGINX Plus R26 及更高版本)
  • RHEL 9.0+
  • Ubuntu 22.04 LTS

为上游服务器和虚拟服务器生成 TLS 指标

当 NGINX Plus 部署为反向代理或负载均衡器时,NGINX Plus API 可为每个上游服务器和虚拟服务器提供有关流量、响应代码和延迟的详细指标,以便客户观察和监控服务器的性能和可用性。

在以前的版本中,当在 NGINX Plus 与上游服务器间使用 HTTPS 连接时(httpstream 上下文,分别使用 proxy_pass https://path-to-upstreamproxy_ssl on 指令建立),NGINX Plus 会生成系统级别的 TLS 活动和错误指标。统计数据包括握手、失败和会话重用(使用 proxy_ssl_session_reuse 指令进行配置)。

NGINX Plus R27 为配置中包含 zone 指令的各个上游服务器以及配置中包含 status_zone 指令的虚拟服务器生成这些 TLS 指标。兼具来自客户端和服务器端的指标有助于解决 TLS 握手方面的问题。

以下示例显示了如何在上游服务器 upstream1 以及为其代理流量的虚拟服务器上收集统计数据。

该输出结果表明,第一台上游服务器参与了四次 TLS 握手和两次复用会话:

$ curl http://127.0.0.1:8000/api/8/http/upstreams/upstream1/servers/0 | jq{
  "peers": [
    {
      "id": 0,
      "server": "127.0.0.1:8081",
      "name": "127.0.0.1:8081",
      "backup": false,
      "weight": 1,
      "state": "up",
      "active": 0,
      "ssl": {
        "handshakes": 4,
        "handshakes_failed": 0,
        "session_reuses": 2
      },
      "requests": 4,
      "header_time": 4,
      "response_time": 4,
      ...
    }
  ]
}

该输出结果表明,NGINX Plus 参与了七次 TLS 握手:

$ curl http://127.0.0.1:8000/api/8/http/server_zones/srv | jq{
  "processing": 0,
  "requests": 7,
  "responses": {
    "1xx": 0,
    "2xx": 7,
    "3xx": 0,
    "4xx": 0,
    "5xx": 0,
    "codes": {
      "200": 7
    },
    "total": 7
  },
  "discarded": 0,
  "received": 546,
  "sent": 1134,
  "ssl": {
    "handshakes": 7,
    "handshakes_failed": 0,
    "session_reuses": 0
  }
  ...
}

请注意,NGINX Plus API 仍同以前的 NGINX Plus 版本一样收集 NGINX Plus 全局 TLS 指标:

$ curl http://127.0.0.1:8000/api/8/ssl | jq{
  "handshakes": 21,
  "handshakes_failed": 0,
  "session_reuses": 6
}

自定义 JWT 验证失败时的错误代码

NGINX Plus R25 引入了 auth_jwt_require 指令,用于在 JWT 验证流程中定义自定义检查。在 NGINX Plus R25 和 R26 中,验证失败时总是返回错误代码 401 (Unauthorized)

NGINX Plus R27 为 auth_jwt_require 指令引入了 error 参数,支持您将每个指令的错误代码分别设置为 401403 (Forbidden)。当用户的访问请求失败时,可通过选择错误代码来区分认证失败(JWT 无效)和授权失败(缺少所需声明)。您还可以为错误代码创建自定义的处理程序,例如返回特殊页面,解释错误产生的原因(通过 error_page 指令),或将访问请求重定向到指定的内部位置,进行进一步处理。

如果以下类型的 JWT 检查失败,将默认返回状态代码 401:

  • 始终执行的(非自定义)检查
  • 使用 auth_jwt_require 而非 error 参数配置的自定义检查

如果在一个 location 块中有多个 auth_jwt_require 指令,则将按照它们出现的先后顺序对其进行取值。第一次失败时停止取值,并返回指定的错误代码。

在以下示例中,如果 $req1$req2 值为空或 0 (zero) ,auth_jwt_require 指令将返回 403

NGINX JavaScript 和 Prometheus-njs 模块的增强功能

NGINX Plus R27 整合了 0.7.3 和 0.7.4 版 NGINX JavaScript 模块,并进行了以下增强。

更多面向 njs Fetch API 的指令

NGINX Plus R24 中整合的 NGINX Javascript 0.5.3 引入了 ngx.fetch 函数(又称为 Fetch API),可在TCP/UDP 连接上下文中,实例化一个简单 HTTP 客户端。(有关该函数用例的讨论,请参阅我们的博文“ 在 TCP.htmlUDP 中使用简单 HTTP 客户端访问 HTTP 服务 ”。)

NGINX Plus R27 引入了以下指令,以微调 Fetch API 的行为:

  • js_fetch_buffer_size[HTTP][Stream] –– 设置读写缓冲区的大小。
  • js_fetch_max_response_buffer_size[HTTP][Stream] –– 设置使用 Fetch API 接收的最大响应长度。
  • js_fetch_timeout[HTTP][Stream] –– 定义两次连续读取或写入操作之间的读写超时(而非整个响应的超时)。如果在超时期间内没有数据传输,则表示该连接已断开。
  • js_fetch_verify[HTTP][Stream] –– 启用或禁用 HTTPS 服务端证书验证。

以十六进制数的形式报告版本号

新增的 njs.version_number 对象以十六进制数的形式报告 njs 模块版本。(现有的 njs.version 对象以字符串的形式报告 njs 模块版本。)

Prometheus-njs 模块可转换更多指标

现在 Prometheus-njs 模块不仅能够将 NGINX Plus 指标转换为 Prometheus 数据格式,还可以转换下列端点上公开的指标:

 

NGINX Plus R27 的其他增强功能

NGINX Plus API 版本变更

NGINX Plus API 的版本号从 7 更新到了 8,以体现为上游服务器和虚拟服务器增加了 ssl 相关的监控指标,参考“为上游服务器和虚拟服务器生成 TLS 指标”部分所述。以前的版本号仍然有效,但输出结果不包括之后的 API 版本中添加的指标。

Linux EPOLLEXCLUSIVE 模式助力更出色的连接分配

当在 Linux 内核中使用 EPOLLEXCLUSIVE 模式时,NGINX Plus R27 能够在 NGINX worker 进程之间更均匀地分配连接。通常,在这种模式下,Linux 内核仅通知第一个将监听套接字添加到 EPOLL 实例的进程。因此,大多数连接都由第一个 worker 进程来处理。NGINX 现在会定期重新添加套接字,以便为其他 worker 进程提供接受连接的机会。

 

升级或试用 NGINX Plus

如果您是 NGINX Plus 用户,我们强烈建议您尽快升级到 NGINX Plus R27。除了上面提到的内容,您还将获得更多修复和改进,并且 NGINX 团队将会在您需要帮助时为您及时提供支持。

如果您还不是 NGINX Plus 用户,我们建议您立即申请试用——它具备强大的安全性,可充当负载均衡器、API 网关或者具备增强的监控和管理 API 的 Web 服务器,并且 NGINX 团队将提供支持服务。请立即下载 30 天免费试用版


"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."