乐趣区

关于监控:n9e监控框架

一.n9e 是什么

n9e 的全称是 Nightingale,与开发 Open-falcon 的是一拨人,起初这波人去了滴滴,开发了 n9e 成为滴滴开源的监控框架。

n9e 在 v5 版本之前,连续了 Open-falcon push 的模式,在告警的业务逻辑和指标展示做了很多优化。

n9e 在 v5 版本至今,应用 prometheus 作为后端的 TSDB,并通过 promQL 作为告警表达式做告警断定。

本文次要关注最新的 v5 版本。

二.n9e 的架构

  • server:后端服务,负责将指标写入 Prometheus,以及告警业务逻辑的实现;
  • webapi:前端服务,负责前端业务逻辑;
  • mysql:保留告警策略,以及告警告诉配置;
  • redis:缓存用户登录信息;

指标的业务逻辑:

  1. 监控 agent 通过 remote-write API,申请 server;
  2. server 对指标进行提取,存入 Prometheus;

告警的业务逻辑:

  1. 用户通过 webapi 配置告警策略,server 将策略保留至 mysql;
  2. server 依据告警周期,定期查问 PromQL 的值是否触发告警;
  3. 若触发告警,则将其存入 mysql,同时进行告警告诉;

三.n9e 的部署和应用

应用部署文档,部署单机版的 n9e 环境,次要部署以下组件:

  • prometheus
  • mysql
  • redis
  • n9e server & webapi

部署胜利后,n9e server 监听在 19000 端口,webapi 监听到 18000 端口;

通过 http://ip:18000 拜访 WEB UI,默认用户:root/root.2020

四.prometheus 作为后端 TSDB

prometheus 通常被用来拉取 exporter 的指标,而后存入本地磁盘;它既实现了拉取的逻辑,也实现 TSDB 的性能。

在 2.25 版本之前,prometheus 不反对独自作为 TSDB,即 不反对 通过 API 间接向 prometheus 写入时序数据。

在 2.25 版本之后,prometheus 配置 –enable-feature=remote-write-receiver 参数后,反对通过 REST 接口向 prometheus 写入时序数据。

n9e 应用 prometheus 2.28 版本,利用了 prometheus 这一个性,将其作为后端的 TSDB。

prometheus 提供的 REST 接口:POST /api/v1/write,能够向 prometheus 写入时序数据;
查看 prometheus 的源码:

// web/api/v1/api.go
func (api *API) Register(r *route.Router) {
    ...
    r.Post("/write", api.ready(api.remoteWrite))
    ......
}

func (api *API) remoteWrite(w http.ResponseWriter, r *http.Request) {
    if api.remoteWriteHandler != nil {api.remoteWriteHandler.ServeHTTP(w, r)
    } else {    // 未配置 remote-write-receiver,返回谬误
        http.Error(w, "remote write receiver needs to be enabled with --enable-feature=remote-write-receiver", http.StatusNotFound)
    }
}

五.telegraf 作为监控 agent 并主动发现

Telegraf 是 InfluxData 开源的一款采集器,能够采集操作系统、各种中间件的监控指标等;

Telegraf 是一个大一统的设计,即一个二进制能够采集 CPU、内存、mysql、mongodb、redis、snmp 等,不像 Prometheus 的 exporter,每个监控对象一个 exporter。

telegraf 作为监控 agent 被部署到监控的指标主机上,同时配置 telegraf,将其采集的指标输入到 n9e server:

vi /opt/telegraf/telegraf.conf
......
[[outputs.opentsdb]]
  host = "http://127.0.0.1"
  port = 19000
  http_batch_size = 50
  http_path = "/opentsdb/put"
  debug = false
  separator = "_"

上述配置,telegraf 采集的指标,通过 http://127.0.01:19000/opentsd… 发到 n9e server,该配置中 telegraf 与 n9e server 部署在一台机器上。

n9e server 实现了 /opentsdb/put 接口,相干的源码:

// src/server/router/router.go
func configRoute(r *gin.Engine, version string) {
    ...
    r.POST("/opentsdb/put", handleOpenTSDB)
    ...
}
func handleOpenTSDB(c *gin.Context) {
    ...
    bs, err = ioutil.ReadAll(c.Request.Body)
    var arr []HTTPMetric
    err = json.Unmarshal(bs, &arr)
    for i := 0; i < len(arr); i++ {pt, err := arr[i].ToProm()
        host, has := arr[i].Tags["ident"]
        // 有 ident 标签
        if has {
            // register host
            ids[host] = ts
        }
        list = append(list, pt)
    }
    if len(list) > 0 {if !writer.Writers.PushQueue(list) {    // 将时序 push 到 queu
            msg = "writer queue full"
        }
        // 将 host 注册进去
        idents.Idents.MSet(ids)
    }
    ...
}

该 API 所做的事件:

  • 提供指标中的 ident 标签,其 value 作为 新发现的 host,被注册到已治理主机列表;
  • 将接管的指标 push 到本地的 Queue,Queue 中的数据前面被 goroutine 发送到 prometheus;

六.grafana-agent 作为监控 agent 并主动发现

grafana-agent 能够拉取各种 exporter 的 /metrics,并将其通过 remote-write API 写入 n9e server。

grafana-agent 还内置了罕用的 exporter,比方 node-exporter。

grafana-agent 的配置文件:

# cat agent.yaml
server:
  http_listen_port: 12345
metrics:
  wal_directory: /tmp/grafana-agent-wal
  global:
    scrape_interval: 15s
    external_labels:
      cluster: mycluster
    remote_write:
    - url: http://172.1.2.3:19000/api/v1/write
    scrape_configs:
    - job_name: "cadvisor"
      static_configs:
      - targets: ['192.168.1.2:19000']
integrations:
  agent:
    enabled: true
  node_exporter:
    enabled: true

上述配置中:

  • grafana-agent 集成了 node_exporter;
  • grafana-agent 拉取 cadvisor 工作的 /metrics;
  • grafana-agent 将采集的指标通过 remote-write 发送到 n9e server;
  • n9e server 接管到指标后,提取其中的 instance label,其 value 作为 新发现的 host,增加到发现的主机列表中;

参考:

  1. 部署: https://n9e.github.io/quickst…
  2. prometheus remote-write-receiver: https://prometheus.io/docs/pr…
  3. grafana-agent docs: https://grafana.com/docs/graf…
退出移动版