NGINX Unit 以新功能(统计引擎!)和精彩规划迎接 2022 年秋季

NGINX | 2022年10月27日

首先,距离我们上次分享动态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.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\" }" 
    } 
}

因此,您可以根据需要突破常规日志格式的限制。

变量的另一个重要用例是路由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 | 2022/02/15

NGINX Plus R26 正式发布

NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
NGINX | 2022/02/10

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击

gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
NGINX | 2021/09/13

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划

了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。

NGINX Plus R19 正式发布
NGINX | 2019/09/03

NGINX Plus R19 正式发布

NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。

NGINX现已正式加入F5
NGINX | 2019/05/09

NGINX现已正式加入F5

NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。

使用NGINX和NGINX Plus实现高性能缓存
NGINX | 2016/08/24

使用NGINX和NGINX Plus实现高性能缓存

我将介绍NGINX在内容缓存和性能方面的工作原理,并分享一些控制NGINX内容缓存方式的技巧。