浏览 723
来自 F5 的 Artem Konev | 2020 年 12 月 16 日
距离上次更新已经有一段时间了,但在这期间我们也没有闲着。在今天的这篇博文中,我们将会介绍今年秋季推出的 NGINX Unit 的主要特性。如果您没有时间阅读全文,就请看这里的要点汇总:现在,您可以运行 ASGI 应用,使用多线程应用请求处理,并在配置中使用正则表达式!接下来,让我们按惯例回顾下 NGINX Unit 1.19.0至 1.21.0 的新增特性。
第一个重大升级是异步服务器网关接口 (ASGI),这是一个相对较新的编程接口,旨在让使用 Python 异步
功能的服务器、框架和应用实现一致性和统一性。
该接口被视为广为使用的 WSGI 的继任者。但是,与 HTTP 特定的 WSGI 不同,ASGI 与协议无关。例如,它支持 WebSocket 应用同基于 HTTP 的应用一样顺畅运行,下文对此进行了详细介绍。
NGINX Unit 自 1.20.0 版开始采用 ASGI,并开始支持 ASGI 3.0。如要使用 ASGI,请将 NGINX Unit 指向 Python 应用模块中与 ASGI 兼容的可调用对象。
NGINX Unit 1.21.0 刚推出不久,将支持扩展到了依赖于双可调用对象机制的传统 ASGI 实施。尽管两个版本的接口之间存在差异,但配置 JSON 相同。对于有两个可调用对象的传统 ASGI,您需要在配置中引用第一个单参数可调用对象。‑这可通过从可调用签名中推断接口版本(WSGI、ASGI 2.0、ASGI 3.0)来实现。如果推断失败,则可以使用新的protocol
选项来暗示预期结果,该方法在应用因使用某些复杂的 ASGI 实施逻辑而干扰 NGINX Unit 的尝试时特别有用:
接下来,我们不会深入探讨 ASGI 的细节,而是会介绍一款紧凑的 Python Web 应用,该应用会针对 URL 的 JSON 数组,返回响应代码的 JSON 数组:
该应用使用
到目前为止,一切都很顺利。下面是测试运行代码:
在上文中,我们提到了 ASGI 的协议无关性。ASGI 规范提供了有关
即使省去所有无关内容,仍说来话长,因此我们就简单介绍下它的功能:
http
和websocket
。当您通过
HTTP 连接时,客户端页面由应用本身提供服务,这符合我们在此的目的。但通常来说,最好使用
NGINX Unit 的共享选项提供静态内容,因为这样就无需调用应用了。最后,我们来看一下情况如何:
显然,两者都运行良好。(莎士比亚爱好者们可能会将两者看作埃尔西诺城堡的哨兵,他们手持《哈姆雷特》,说道“异步还是同步?这都不是问题。”)
NGINX Unit 的另一项重大增强是支持扩展应用线程,而不仅仅是进程。借助 NGINX Unit 1.21.0,您可以通过在应用进程中运行多线程实例来微调语言运行时的性能。到目前为止,该机制仅适用于 Java、Perl、Python 和 Ruby,尚不支持其他语言。
应用进程的线程行为由应用特定的threads
配置选项控制:
该选项可设置每个应用进程的 worker 线程数,因此上述配置总共会产生 2×6 = 12 个线程,并且每条线程都是异步工作。请注意,NGINX Unit 不会自动扩展线程数(但会自动扩展应用进程)。您设置的值在进程的整个生命周期内都将保持不变。
另一个名为thread_stack_size
的自定义设置适用于 Java、Perl 和 Python;顾名思义,它设置应用线程堆栈的大小(以字节为单位)。
NGINX Unit 1.21.0引入了我们期待已久的特性 - 正则表达式 (regex)。目前,正则表达式仅适用于最需要的地方:路由。别忘了,路由引导请求通过每个步骤,后者由可选的匹配条件和相应操作构成。对此,正则表达式可助以一臂之力。
NGINX Unit 以前仅支持少量必要的通配符和匹配修饰符,但这已成为过去。现在,您可以在 NGINX Unit 提供的请求属性上充分利用正则表达式,但source
、destination
和scheme
除外。最后一个属性只能进行两种设置:http
和https
,因此不需要正则表达式支持。前两个属性基于 IP 地址,因此人们很难想到使用正则表达式。
现在,让我们看一下,正则表达式可如何帮助您简化 NGINX Unit 配置。请看以下示例:
这段代码摘自在 NGINX Unit 1.21.0 推出之前的真实应用配置。其中大部分代码都能通过字面意思理解:如果请求 URI 与这些模式匹配(少数例外前面添加感叹号),则返回 403 响应代码。简单吗?简单,但极其繁琐,且难以控制。
使用正则表达式的路由也可实现相同目标,步骤如下所示:
可以看到,正则表达式让匹配规则变得更加紧凑。此外,您还可以适时将该方法与 glob 模式结合使用(例如此处的"!/data/webdot/*.png"
模式)。‑
简单介绍一下正则表达式语法:实际上,NGINX Unit 通过 Perl 兼容正则表达式 (PCRE) 实施正则表达式(除非您修改了编译选项),从而建立语法。但是,这些模式是用 JSON 字符串编写的,因此必须正确地将其转义(请注意上面示例中的双反斜杠)。还请注意,属性值在匹配之前已被标准化:NGINX Unit 插入百分比编码的字符、调整大小写、合并斜杠等。
NGINX Unit 的进程隔离特性支持您使用rootfs
选项更改文件系统根。为了确保在文件系统根更改后,其应用仍可正常运行,默认情况下会自动挂载多个目录,其中包括应用语言运行时依赖项,例如 Python 的 sys.path目录,以及
如果被隔离的应用不需要此操作,则可以使用新的automount
选项禁用这些挂载点:
fastcgi_finish_request()
NGINX Unit 1.21.0还新增了对 PHP
函数的支持。它通过刷新响应数据并最终确定响应,之后再继续执行可能需要一段时间但不产生任何输出的任务,实现 PHP 异步处理:
在此处,fastcgi_finish_request()
调用紧跟用户可见的响应,并在可能耗时的调用之前完成响应;因此,我们无需等待连接即可通知用户。
考虑到安全性,NGINX Unit 以前限制有效的 HTTP 请求标头字段只能使用字母数字字符组和连字符,最终证明,这种限制会干扰少数依赖非常规标头字段名称的应用。在 NGINX Unit 1.21.0中,此行为由名为discard_unsafe_fields
的新配置选项控制。默认情况下,该选项被设置为 true,这样,NGINX Unit 就可以像从前一样从请求中删除此类标头字段,不过您也可以禁用该选项,如下所示:
选项
Python 应用的全新callable
选项明确指定了要启动的可调用对象。以前,NGINX Unit 要求必须将可调用对象命名为application
;对于某些用户来说,这并非易事,尤其是在涉及第三方应用时。从 NGINX Unit 1.20.0开始,您可以指定其他名称(在本示例中为app
)。如果可调用对象名为application
,则可以忽略callable
选项。
NGINX Unit 1.19.0对请求路由机制做了微小的调整,但效果十分明显:现在,可以使用配置变量定义侦听器或路由过程。目前,共有三个变量:$host
、$method
和$uri
。见名知意,这里就不介绍它们各自的含义了,我们重点讨论下它们如何影响 NGINX Unit 的路由机制。
目前,变量只能出现在pass
目的地。在运行时,NGINX Unit 分别用标准化的Host
标头字段、HTTP 方法名称和 URI 进行替换,从而实现简单而通用的路由方案。为方便理解,我们现在举例说明一下。该示例配置依赖$host
变量(从传入请求填充)实施一个可选择本地查询 (localhost
) 或远程 (www.example.com
) 查询的简单而通用的路由方案:
以上就是我们对 NGINX Unit 最新升级的简短回顾。工作还在继续,我们目前正在解决运行指标 API 和上游 keepalive 连接缓存问题。
同往常一样,诚邀您查看我们的路线图(您可以在这里了解到您最喜欢的特性近期是否会实施),并对我们的内部计划进行评分和评论。‑欢迎您随时在
有关版本 1.19.0、1.20.0 和 1.21.0 的变更和漏洞修复的完整列表,请查看
NGINX Plus 订户可免费获得 NGINX Unit 支持。立即下载
原英文博客:https://www.nginx.com/blog/nginx-unit-updates-for-autumn-2020-now-available/
按点赞数排序
按时间排序