首先,距离我们上次分享动态NGINX Unit团队的消息已经过去很长时间了。这段动荡时期影响了每个人,我们也不例外。今年3月,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
{
"connections": {
"accepted": 1067,
"active": 13,
"idle": 4,
"closed": 1050
},
"requests": {
"total": 1307
},
"applications": {
"wp": {
"processes": {
"running": 14,
"starting": 0,
"idle": 4
},
"requests": {
"active": 10
}
}
}
}此处大多数字段的含义一目了然:connections(第 2 行)和requests(第 9 行)提供实例范围的数据,而applications对象(第 13 行)与/config/applications相对应,涵盖与该应用程序直接相关的进程和请求。
第3–6行显示了NGINX Unit跟踪的4种连接类别:accepted、active、idle和closed。进程分为以下类别:running、starting和idle(第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.htmlHTTP/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\" }"
}
}因此,您可以根据需要突破常规日志格式的限制。
变量的另一个重要用例是路由location值,该值属于路由action:
{
"action": {
"return": 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、协议转发”。
改版后的share选项
NGINX Unit 1.11.0版引入了share路由选项,用于提供静态内容。该选项类似于NGINX中的root指令:
{
"share": "/path/to/dir/"
}最初,share选项指定所谓的文档根目录。为了确定要提供哪个文件,Unit只需将请求中的URI附加到此share路径。例如,对于请求/some/file.html的简单GET请求,Unit会提供/path/to/dir/some/file.html。不过,我们不断遇到需要更精细地控制文件路径的边界情况,因此决定改进这一机制。从1.26.0版开始,share选项指定共享文件的完整路径,而不再只是文档根目录。
想要提供特定文件?可以:
{
"share": "/path/to/a/file.html"
}需要在路径中使用变量?没问题:
{
"share": "/www/data/$host/app.html"
}不过,如何模拟您已熟悉的NGINX和旧版Unit的行为?还记得前几段中被我们视为已过时的文档根目录吗?我们有解决方案。
现在可以像这样重写配置:
{
"share": "/www/data/"
}如下所示,将请求的URI显式附加到路径中!
{
"share": "/www/data/$uri"
}最后,share 指令现在可以接受路径数组,并逐一尝试这些路径,直到找到文件:
{
"share": [
"/www/$host$uri",
"/www/static$uri",
"/www/app.html"
]
}如果未找到文件,路由将转至fallback操作;如果没有fallback,则返回404 (Not Found)状态码。
有关更多详细信息,请参阅NGINX Unit文档中的“静态文件”。
计划:njs、URI重写、操作链、OpenAPI
当您读到这里时,我们已经开始着手开发下一个版本。下面先简要介绍一下我们正在筹备的内容。
首先,我们正在将NGINX Unit与NGINX JavaScript模块(njs)集成。后者是NGINX正在积极开发的另一个主力项目。简而言之,这意味着NGINX Unit将支持调用JavaScript模块。请看以下示例:
var hellonjs = {}
hellonjs.hello = function(vars) {
if ('unitvar' in vars) {
return vars.unitvar;
} else {
return 'default';
}
}
export default hellonjs在NGINX Unit中导入该模块后,您可以通过配置实现一些实用功能:
{
"match": {
"uri": "~(?.*)" }, "action": { "share": "`/www/html${hellonjs.hello(vars)}`" } }此外,我们还计划引入类似于广受欢迎的NGINX rewrite指令的功能:
{
"match": {
"uri": "/app/old_path"
},
"action": {
"rewrite": "/app/new_path",
"pass": "routes"
}
}不过,我们的计划不止于此。何不将NGINX Unit的路由与应用本身的输出关联起来(也称为action链式调用)?
{
"action": [
{
"pass": "applications/auth_check"
},
{
"pass": "applications/my_app"
}
]
}这里的思路是由auth_check应用对传入请求进行身份验证,并返回状态码以指示结果。如果身份验证成功,则返回200 OK,并将请求传递给my_app。
与此同时,我们也在制定一份OpenAPI规范,以全面、准确地定义NGINX Unit的API及其具体功能。这项工作规模庞大,祝我们好运。
如果这些仍不足以满足您的好奇心,请查看我们的路线图,详细了解各项计划。该路线图支持互动,欢迎各位读者提出意见。
相关博客文章
NGINX Plus R26 正式发布
NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。
使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。
Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。
NGINX Plus R19 正式发布
NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。
NGINX现已正式加入F5
NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。
