点赞
评论
收藏
分享
举报
2020 年秋季 NGINX Unit 更新
发表于2021-03-04 16:15

浏览 3.2k

来自 F5 的 Artem Konev | 2020 年 12 月 16 日

距离上次更新已经有一段时间了,但在这期间我们也没有闲着。在今天的这篇博文中,我们将会介绍今年秋季推出的 NGINX Unit 的主要特性。如果您没有时间阅读全文,就请看这里的要点汇总:现在,您可以运行 ASGI 应用,使用多线程应用请求处理,并在配置中使用正则表达式!接下来,让我们按惯例回顾下 NGINX Unit 1.19.0至 1.21.0 的新增特性。

Python:ASGI 支持

第一个重大升级是异步服务器网关接口 (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 数组:


该应用使用asyncio和aiohttp模块,前者是 Python 标准库的一部分,而后者则在前者的基础上提供异步 HTTP 功能。 现在,我们将该模块插入 NGINX Unit,看看会发生什么:

到目前为止,一切都很顺利。下面是测试运行代码:

在上文中,我们提到了 ASGI 的协议无关性。ASGI 规范提供了有关 WebSocket 连接范围的详细信息,可用于实施 WebSocket-over-ASGI方法。现在,我们使用 Apache Tomcat WebSocket 示例中的在线聊天简明版进行下说明:


即使省去所有无关内容,仍说来话长,因此我们就简单介绍下它的功能:

  • 脚本同时包含了 ASGI 服务器的 Python 代码和客户端页面的 JavaScript/HTML 代码。
  • ASGI 服务器具有两个 ASGI 连接范围:http和 websocket。当您通过 HTTP 连接时,客户端页面由应用本身提供服务,这符合我们在此的目的。但通常来说,最好使用 NGINX Unit 的共享选项提供静态内容,因为这样就无需调用应用了。
  • 客户端代码会与服务器建立 WebSocket 连接,并运行各种消息传递事件循环,显示其从服务器接收到的更新。
  • 服务器代码的 WebSocket 部分接受新连接,向现有用户广播新用户通知,并接收用户消息,然后将其广播给所有用户。

最后,我们来看一下情况如何:


显然,两者都运行良好。(莎士比亚爱好者们可能会将两者看作埃尔西诺城堡的哨兵,他们手持《哈姆雷特》,说道“异步还是同步?这都不是问题。”)

Java、Perl、Python、Ruby:多线程请求处理

NGINX Unit 的另一项重大增强是支持扩展应用线程,而不仅仅是进程。借助 NGINX Unit 1.21.0,您可以通过在应用进程中运行多线程实例来微调语言运行时的性能。到目前为止,该机制仅适用于 Java、Perl、Python 和 Ruby,尚不支持其他语言。

应用进程的线程行为由应用特定的threads配置选项控制:

该选项可设置每个应用进程的 worker 线程数,因此上述配置总共会产生 2×6 = 12 个线程,并且每条线程都是异步工作。请注意,NGINX Unit 不会自动扩展线程数(但会自动扩展应用进程)。您设置的值在进程的整个生命周期内都将保持不变。

另一个名为 thread_stack_size的自定义设置适用于 Java、Perl 和 Python;顾名思义,它设置应用线程堆栈的大小(以字节为单位)。

面向路由的 PCRE 正则表达式

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目录,以及 procfs和tmpfs目录。

如果被隔离的应用不需要此操作,则可以使用新的automount选项禁用这些挂载点:

PHP:支持fastcgi_finish_request()

NGINX Unit 1.21.0还新增了对 PHP fastcgi_finish_request()函数的支持。它通过刷新响应数据并最终确定响应,之后再继续执行可能需要一段时间但不产生任何输出的任务,实现 PHP 异步处理:


在此处,fastcgi_finish_request()调用紧跟用户可见的响应,并在可能耗时的调用之前完成响应;因此,我们无需等待连接即可通知用户。

HTTP 标头可包含扩展字符

考虑到安全性,NGINX Unit 以前限制有效的 HTTP 请求标头字段只能使用字母数字字符组和连字符,最终证明,这种限制会干扰少数依赖非常规标头字段名称的应用。在 NGINX Unit 1.21.0中,此行为由名为discard_unsafe_fields的新配置选项控制。默认情况下,该选项被设置为 true,这样,NGINX Unit 就可以像从前一样从请求中删除此类标头字段,不过您也可以禁用该选项,如下所示:


Python:全新可调用对象选项

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 连接缓存问题。

同往常一样,诚邀您查看我们的路线图(您可以在这里了解到您最喜欢的特性近期是否会实施),并对我们的内部计划进行评分和评论。‑欢迎您随时在 GitHub存储库中提问,并分享您的改进建议。

有关版本 1.19.0、1.20.0 和 1.21.0 的变更和漏洞修复的完整列表,请查看 NGINX Unit 变更日志。

NGINX Plus 订户可免费获得 NGINX Unit 支持。立即下载30 天免费试用版,或与我们联系以讨论您的用例。

原英文博客:https://www.nginx.com/blog/nginx-unit-updates-for-autumn-2020-now-available/

已修改于2023-03-05 01:28
创作不易,留下一份鼓励
NGINX官方账号

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
NGINX官方账号
这家伙很懒还未留下介绍~
335
文章
21
问答
201
粉丝
相关文章
前言:随着现代应用架构的发展和演进,特别是容器云的盛行,越来越多的用户将7层流量的控制从前端网络的应用交付设备转向到了在每个应用,微服务前的软负载SLB上。典型的SLB,如nginx,部署位置可以在网络边界,在服务器的前端,在容器云中,以反代,微网关,sidecar的形式存在。因为业务在不断的变化,特别是随着devops文化的流行,业务变化的频率和业务对基础架构的诉求也在不断上升。因此,我们也在nginx上交付了越来越多的应用服务,其中就包括了大家熟悉的黑白名单功能。从现代的安全架构上来看,内网是不安全的,这件事情也得到了共识,从而出现了零信任架构,出现了无界的安全,出现了双模安全,基于每个应用的定制化精细化安全策略的诉求也就出现。那么如何基于每个应用或微服务,进行频率的控制是保证应用的稳定性,健壮性,可用性的关键。限流是一个很好的方法,但是静态的限流很容易被绕过,应用层的ddos攻击往往会压着访问频率,那么如果能够准确定位出每个客户端,每个session的请求频率,自动的把超出阈值的客户端加黑封禁一段时间,比如说3分钟,这样就可以实现自动化的黑白名单,保护服务的健壮性。当然,还有
点赞 1
浏览 4.1k
社区举办的开发者线下沙龙“燥起来,开发者!NGINX技术的热潮。社区组委会召集人,F5中国区资深市场总监王学军、F5Networks资深方案顾问熊平、NGINX UNIT开源软件”主题展开了精彩NGINX
点赞 0
浏览 3.3k
目录问题背景解决思路网络拓扑搭建Macvlan命名空间测试命名空间网络连通性启动nginx服务结语1、问题背景  一种多租户多Nginx集群部署的上云解决方案示意图如图1所示:图1一种多租户多Nginx集群部署示意图  该方案主要包含三部分,分别为APIServer,配置中心及集群部署节点,各部分实现的功能为:APIServer:Nginx集群服务的总入口,负责接收各类管控信息,并将请求信息解析后转发至配置中心;配置中心:负责不同租户Nginx实例的安装部署与配置管理;集群部署节点:不同租户在不同节点上部署Nginx实例,实现实例级别的高可用;  如图1所示,要实现高可用的部署方式,就要求在每一个服务器node节点上部署的Nginx实例分属于不同的租户;要实现每个node节点的Nginx实例分属于不同的租户,就要求在node节点实现租户隔离。这里的租户隔离至少需要包含两个属性,一个是网络资源的隔离,一个是Nginx实例端口占用的隔离。2、解决思路为了在同一台node节点实现租户隔离,目前常见的有以下几
点赞 1
浏览 5.1k