3

对于 Nginx Amplify 不了解的同学,可以搜索一下,在 Nginx 官网上有介绍。
简单来说,就是你可以在服务器上安装一个开源的 Python 写的 Agent。这个 Agent 会上传你的 Nginx 实例各种运行时数据到 Nginx.inc 的(闭源)SAAS平台上。
通过这个 SAAS 平台,Nginx.inc 可以替你提供诸如配置检查和优化、监控、报警等功能。

我第一次听到它,是在今年 Nginx.conf 放出的一个视频:NGINX: Past, Present, and Future
这个演讲就是在大会开始的时候,由 Nginx 官方的主持人回顾历史、总结现在、展望未来。在展望未来的这一篇章中,主持人介绍了 Nginx Amplify,并演示了它的功能。
由于部门内 Nginx 的监控由我所在的 team 负责,出于专业敏感性,听完之后我就开始搜索 Nginx Amplify 相关内容。

在阅读了它的 Agent 源码之后,我的结论是,Nginx Amplify 并没有什么用。

首先,它的 Agent 是独立于 Nginx 运行的,这意味着获取各项指标的能力会受到限制。如果是一个独立的 Nginx 模块,其能力应该会更强。

其次,这个 Agent 需要跟 SAAS 平台通讯。尽管这个通讯走 https,不过即使不知道通讯的内容,只知道通讯的模式,就可以挖掘出许多有用的数据。
要让部署在内网的 Nginx 服务器跟云端平台通讯,这个很难说服别人这么做。

最后,也是最重要的理由:这个 Nginx Amplify 没有什么新意。

Nginx Amplify Agent 采集的数据源分为三类,Nginx/Nginx Plus/System。抛开 Nginx Plus 不谈,下面是 Agent 现在采集的指标内容:

  • Nginx

    • Nginx 配置

    • stub_status暴露出来的数据

    • access_log,通过类似于 tail -f 的方式读取日志文件获取

    • error_log,同上

    • /proc/<nginx_pid> 相关的数据。这是通过 psutils 获取的

  • System

    • /proc/ 下面的数据。也是通过 psutils 获取的

    • 其他零零碎碎的系统数据

具体代码在 collectors 下面,感兴趣的同学可以看下。

老实说,上面列出的各个指标,除了Nginx 配置/proc相关的,我们都已经在采集了。

我们业务用的是 Nginx 的一个衍生版本——OpenResty,它以 lua API 的形式开放了一些相关的 Nginx 接口,允许通过 lua 代码去操作 Nginx 中的数据。

对于 stub_status,它的采集数据可以通过如下的变量获取:

$connections_active
    same as the Active connections value;
$connections_reading
    same as the Reading value;
$connections_writing
    same as the Writing value;
$connections_waiting
    same as the Waiting value

我们可以通过ngx.var.connections_active这样的形式去获取该变量的值。

对于 access_log,我们目前是在 OpenResty 的 log_by_lua 阶段,去获取跟请求和响应相关的各种数据,包括状态码、响应时间等等。
这些数据会被记录到每个 Worker 线程独立的 LRU Cache 中,然后通过 ngx.timer 周期性地汇总到跨进程的 shared_dict 里。
汇总的数据可以通过后台任务定期去读取、上报。这个后台任务也是在 OpenResty 内部启动的。
通过 access_log 去获取相关的日志数据,受限于 access_log 的文件格式。而在 Nginx 请求上下文去记录数据,则更加方便得多。

对于 error_log,由于 error_log 不像 access_log,没有一个专门的阶段进行处理,我们无法通过 lua 代码的方式介入处理。
目前的做法是引入二次开发过的 filebeat 作为 Agent,上传日志内容到日志处理系统。
当然你也可以把 error_log 写到 syslog,或者写入 stderr。这些都是支持的。总之,玩法有很多,用什么取决于现有的监控/日志系统是怎么工作的。

对于 /proc 的数据,考虑到 lua 现在并没有 lua-psutils 这样的库,如果要想获得进程或系统级别的数据,就只能自己写 C 模块调操作系统 API 了。
无论选择 lua 自带的 C binding,还是 luajit 的 ffi,这条路都不会太难走。

至于 Nginx 配置的检查和优化,这一部分并没有开源出来。Agent 里面也只是上传了配置文件而已。
不过如果有必要做,通过前面的几个方式,我们已经采集了不少服务的运行数据了,根据这些数据调整下配置参数也不难。

在官方的演示中,我看到 Nginx Amplify 的监控指标是可以动态设置的。这算不上什么黑魔法。
前面说到我们在 log_by_lua 里面去获取相关的各种数据,这部分的获取逻辑可以是动态的。
获取的逻辑能够在 LRU Cache 中配置,依靠定时任务从 redis 中更新。
如果不喜欢 pull,也可以开个 'light thread',订阅 redis 的变化,由 redis 推到每个 Nginx Worker 进程。

总而言之,Nginx Amplify 只是将现存的监控方式炒冷饭而已。
当然了,我们这种付不起 Nginx Plus 订阅费,只能自己实现相似功能的穷光蛋部门,自然不会是 Nginx Amplify 的目标客户。
所以我大可放心抬杠,无需担心影响别人家的生意。

不过有个 Nginx Amplify Agent 是个好事,尤其当这个 Agent 是运行在 Nginx 外部。也许 Nginx 将来会因此开放出更多监控相关的接口,到时我们就可以顺势而为啦。


spacewander
5.6k 声望1.5k 粉丝

make building blocks that people can understand and use easily, and people will work together to solve the very largest problems.