博客 | NGINX

NGINX Unit 以新功能(统计引擎!)和激动人心的计划迎接 2022 年秋季

NGINX-F5-horiz-black-type-RGB 的一部分
Artem Konev 缩略图
阿尔乔姆·科涅夫
2022 年 10 月 27 日发布

首先要说的是:我们已经有一段时间没有分享 NGINX Unit 团队的新闻了——这些动荡的时期影响了每个人,我们也不例外。 今年三月,Unit 团队的两位创始成员 Valentin Bartenev 和 Maxim Romanov 在为NGINX Unit投入了多年的心血和大量的创造力后,决定转向其他机会。 让我们给予应得的赞扬:没有他们,NGINX Unit 就不会取得如今的成就。 谢谢你,伙计们。

尽管如此,我们的决心依然坚定,我们致力于实现 NGINX 联合创始人 Igor Sysoev 对 NGINX Unit 的最初愿望。 两位新团队成员 Alejandro Colomar 和 Andrew Clayton 的加入促进了开发进程,因此现在我们有不少来自NGINX Unit 1.25 至 1.28 版本的值得注意的项目可以与您分享。

可观察性已成为现实

可观察性一直是 Unit 的主要愿望之一,而 1.28.0 版本包含了最令人期待的功能之一的第一次迭代:统计引擎。 其输出公开在新的/status API 端点:

$ curl --unix-socket /var/run/control.unit.sock http://localhost/status

{
“连接”:{
“已接受”: 1067,
“活动”: 13,
“空闲”: 4,
“关闭”: 1050
},

“请求数”: {
“总计”: 1307
},

“应用”:{
“可湿性粉剂”:{
“流程”:{
“跑步”: 14,
“开始”: 0,
“空闲”: 4
},

“请求”:{
“活动”: 10
            }
        }
    }
}

这里的大多数字段都是自描述的:连接(第 2 行)和请求(第 9 行)提供实例范围的数据,而应用对象(第 13 行)镜像/config/ 应用 ,涵盖了特别关注应用的进程和请求。

第 3-6 行显示 NGINX Unit 跟踪的四类连接: acceptedactiveidleclosed 。 进程的类别有正在运行正在启动空闲(第 16-18 行)。 这些类别反映了连接和进程的内部表示,因此现在您对它们的了解与您的服务器一样多。

看起来很简洁? 目前需要知道的基本上就是这些了。 当然,我们正在努力公开更多有用的指标;但是,您已经可以从命令行查询此 API 来查看服务器上发生的情况,甚至可以将输出插入仪表板或您选择的更奇特的方法。 也许您没有仪表板? 好吧,我们的一些计划包括提供内置的,所以请关注我们,看看它是如何实现的。

有关更多详细信息,请参阅 NGINX Unit 文档中的使用情况统计

变量越多,使用的地方就越多

自 1.24 版以来引入的变量列表非常广泛,包括$body_bytes_sent$header_referer$header_user_agent$remote_addr$request_line$request_uri$status$time_local

其中大多数都相当简单,但以下是一些更值得注意的:

  • $request_uri包含请求 URI 的路径和查询,并保留浏览器编码
  • 类似名称的$request_line存储整个请求,例如GET /docs/help.html HTTP/1.1 ,用于记录日志……
  • $status包含 HTTP 响应状态代码

你注意到了吗? 我们提到了回应。 是的,我们也正在进入这个领域:早期 Unit 版本中的变量侧重于传入请求,但现在我们也有捕获响应属性的变量,例如$status$body_bytes_sent

关于使用变量的新地方,首先要提到的是新的可定制访问日志格式。 想要在 NGINX Unit 的日志条目中使用 JSON? 除了指定简单的路径字符串之外, access_log选项还可以是设置日志条目格式的对象:


{ 
“access_log”:{
“path”:“/var/log/unit/access.log”,
“format”:“{ \“remote_addr\”:\“$remote_addr\”, “time\”:\“$time_local\”, \“request\”:\“$request_line\”, \“response\”:\“$status\”, \“header_referer\”:\“$header_referer\”, \“header_user_agent\”:\“$header_user_agent\” }” 
} 
}

因此,您可以以任何您喜欢的方式超越通常的日志格式。

变量的第二个值得注意的用例是路线操作位置值:


{ 
“动作”:{ 
“返回”: 301, 
“location”:“https://$host$request_uri” 
} 
}

这里我们使用$request_uri通过 HTTPS 将请求(包括查询部分)转发到同一个网站。

chroot选项现在像share选项一样支持变量,这是合乎逻辑的:


{ 
“action”:{ 
“share”:“/www$uri”,
“chroot”:“/www/data/$host/” 
} 
} 

NGINX Unit 现在也支持动态变量。 请求参数、cookie 和标头作为变量公开:例如,查询字符串Type=car&Color=red会产生两个参数变量, $arg_Type$arg_Color 。 在运行时,这些变量会扩展为动态值;如果引用不存在的变量,则该变量被视为空。

有关更多详细信息,请参阅 NGINX Unit 文档中的变量

广泛支持X-Forwarded-*标头

您提出要求,我们满足。 从 1.25.0 版本开始,NGINX Unit 为其侦听器提供了一些 TLS 配置功能,包括一定程度的X-Forwarded-*感知;现在,您可以在侦听器的配置中配置客户端 IP 地址和协议替换:


{
    "listeners": {
        "*:80": {
            "pass": "routes/my-app",
            "forwarded": {
                "client_ip": "X-Forwarded-For",
                "protocol": "X-Forwarded-Proto",
                "recursive": false,
                "source": [
                    "198.51.100.1-198.51.100.254",
                    "!198.51.100.128/26",
                    "203.0.113.195"
                ]
            }
        }
    },
    ...
}

笔记: 此新语法弃用了以前的client_ip语法,该语法将在未来的版本中被删除。

有关更多详细信息,请参阅 NGINX Unit 文档中的“IP、协议转发”

改革后的股票期权

NGINX Unit 版本 1.11.0 引入了用于提供静态内容的共享路由选项。 它与 NGINX 中的root指令类似:


{
“共享”:“/path/to/dir/”
}

最初,共享选项指定了所谓的文档根目录。 为了确定要提供哪个文件,Unit 只需将请求中的 URI 附加到此共享路径即可。 例如,响应对/some/file.html的简单GET请求,单元提供/path/to/dir/some/file.html服务。 尽管如此,我们仍然不断遇到需要对文件路径进行更精细控制的边界情况,因此我们决定进行改进。 从 1.26.0 版本开始,共享选项指定共享文件的完整路径,而不仅仅是文档根目录。

您想提供特定文件吗? 美好的:


{
“共享”:“/path/to/a/file.html”
}

在路径内使用变量? 很酷,没问题:


{
“共享”:“/www/data/$host/app.html”
}

但是你如何模仿你已经习惯的 NGINX 和以前的 Unit 版本的行为呢? 您知道吗,我们在前几段中认为文档根目录已经过时了? 我们有一个解决方案。

您现在可以像这样重写配置:


{
“共享”:“/www/data/”
}

如下,将请求的 URI 附加到路径,但要明确!


{
“共享”:“/www/data/$uri”
}

最后, share指令现在可以接受一个路径数组,逐个尝试,直到找到一个文件:


{
“共享”:[
“/www/$host$uri”,
“/www/static$uri”,
“/www/app.html”
]
}

如果没有找到文件,路由将转到 倒退 行动;如果没有 倒退404 (不是 成立) 返回状态代码。

有关更多详细信息,请参阅 NGINX Unit 文档中的静态文件

计划:njs、URI 重写、动作链、OpenAPI

当您读到这篇文章时,我们已经开始着手下一个版本的发布;以下是我们即将推出的一些新功能。

首先,我们将 NGINX Unit 与 NGINX JavaScript 模块 ( njs ) 集成,后者是 NGINX 正在积极开发的另一个主力项目。简而言之,这意味着 NGINX Unit 将支持调用 JavaScript 模块。 考虑一下:


var hellonjs = {}

hellonjs.hello = 函数(vars) {
    if ('unitvar' in vars) {
        返回 vars.unitvar;

    } 别的 {
        返回“默认”;
    }
}

导出默认的 hellonjs

在 NGINX Unit 中导入模块后,您将能够使用配置做一些有趣的事情:


{ “match”:{ “uri”:“~(?.*)” }, “action”:{ “share”:“`/www/html${hellonjs.hello(vars)} `" } }

此外,我们还计划引入类似于广受欢迎的 NGINX重写指令的功能:


{
“match”:{
“uri”:“/app/old_path”
},

“action”:{
“rewrite”:“/app/new_path”,
“pass”:“routes”
}
}

但我们的计划并不止于此。 如何将 NGINX Unit 的路由与应用程序本身的输出绑定(又称动作链)?


{
“行动”: [
{
“通过”:“应用/auth_check”
},
{
“pass”:“应用/my_app”
}
]
}

这里的想法是auth_check应用程序验证传入的请求并返回状态代码来指示结果。 如果身份验证 成功, 200 好的 被返回,请求传递给 我的应用程序

同时,我们还在致力于制定OpenAPI规范,以一劳永逸地定义 NGINX Unit 的 API 及其确切功能。 祝我们好运,因为这是一项艰巨的任务。

如果这还不足以满足您的好奇心,请参阅我们的路线图,以详细剖析我们的计划;它是交互式的,所以亲爱的读者,我们非常欢迎您提供任何意见。


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