时间是我们业务的重要组成部分,因此我必须对服务器的时间进行强有力的监控。为此,我在服务器中设置了 prometheus
node-exporter
,以从 node_time_seconds
指标获取服务器的时间。
我们的服务器时间应该与一个外部源同步(即 timeanddate.com),并且我部署了一个应用程序,以便在调用此域时通过 API 获取该源以 Unix 纪元格式报告的时间:http://time -exporter.mydomain.local/metrics.
考虑以下指标:
由 node_time_seconds
作业的
node-exporter
指标报告的服务器时间:
node_time_seconds 1.7223269513417892e+09
timeanddate_current_time_seconds
作业的 time-exporter
指标报告的外部参考时间:
timeanddate_current_time_seconds 1722326859
node_time_seconds
中减去 timeanddate_current_time_seconds
指标,我得到服务器报告的时间与外部参考报告的时间之间的差异(即 node_time_seconds
- timeanddate_xurrent_time
),并且如果该值大于 1(秒),prometheus 的警报管理器向我发送警报。
但是我在这里面临的问题是,考虑到普罗米修斯的
scrape_interval
为 120 秒,当我减去这两个指标并获得时间差时,它会为每个实例(服务器)返回 0 到 120 范围内的值。这是因为普罗米修斯在抓取间隔内抓取 node-exporter
作业和 time-exporter
作业的时间存在差异。例如,prometheus 在抓取间隔的第 20 秒抓取了 node-exporter
,并在抓取间隔的第 100 秒抓取了 time-exporter
。两者都返回被抓取的正确时间,但是减去指标后得到的值为 80,并且不接近于零。
我用来获取时差的查询如下:
abs (last_over_time(node_time_seconds [2m]) - ignoring (instance,job) group_left last_over_time(timeanddate_current_time_seconds[2m]))
请注意,由于实例和作业名称以及多对一查询结构的差异,我使用
ignoring
和 group_left
函数。还可以使用 last_over_time
函数获取最新的点值。
正如 ChatGPT 所建议的,我还尝试了以下查询:
abs ( abs(node_time_seconds - timestamp(node_time_seconds)) - ignoring (instance,job) group_left abs(timeanddate_current_time_seconds - timestamp(timeanddate_current_time_seconds)))
虽然它返回的值低于 1 秒,但这也没有意义,因为
time_stamp
函数返回的是基于 prometheus 服务器时间抓取样本的时间,并且可能不准确。
我想知道是否有办法确保 Prometheus 同时抓取两个指标或更好地对齐它们的抓取。
任何见解或建议将不胜感激。预先感谢!
P.S
curl -s http://time-exporter.mydomain.local/metrics | tail -n 1 | awk '{print $2}' && curl -s http://<some_ip>:9100/metrics | grep "^node_time_seconds" | awk '{print $2}'
Prometheus 不提供同时针对不同目标对齐刮擦的功能。解决方案是在Prometheus运行的服务器上设置参考时间。然后 Prometheus 会在抓取期间将参考时间存储为指标时间戳,因此您可以使用以下 PromQL 查询来针对抓取目标处大于一秒的时间差异发出警报:
abs(time() - node_time_seconds) > 1
附注您可以使用我正在开发的类似 Prometheus 的替代监控解决方案 - VictoriaMetrics 和/或 vmagent。它支持通过抓取配置中的
scrape_align_interval
选项来调整不同目标的抓取时间 - 请参阅这些文档。请注意,单节点 VictoriaMetrics 无需 vmagent 即可抓取目标 - 请参阅这些文档。