Posts for Tag: 监控系统

使用PromeQL/MetricsQL实现宕机报警思路

宕机报警的意义

保证机器从系统外部访问的可达性。

如果机器从系统外部无法访问,那便是宕机报警(或我们认为的宕机报警)。


思路

每台机器上都运行着我们的监控Agent,代码健壮的情况前提下,可以忽略Agent异常退出(或Agent异常退出概率极低)的情况,我们视Agent数据未如期上报的情况为宕机情况。

所以便得到一个公式:

宕机报警 == 失联报警 == 数据断点检测

断点检测,依赖Metrics指标的及时上报,最好不使用单次上报容易超时的数据类型,所以心跳是最合适的数据。

所以重新明确目标: 宕机报警 == 心跳断点检测。 (断点时间与阈值时间进行比较)


如何对心跳数据做断点检测?

如果心跳指标是heartbeat,使用ip作为label来确保机器唯一性

指标为:

heartbeat{ip="10.58.99.166"}

正常情况下,会上报value = 1

异常情况下,会没有数据

所以我们可以使用MetrisQL中的absent_over_time函数来进行心跳断点检测:

absent_over_time(heartbeat{ip="10.58.99.166"}) == 1

absent_over_time(query)函数在query表达式没有数据的时候返回1,所以当整个表达式 == 1时,就能够检测到心跳断点。

值得注意的是:query表达式必须返回单条线而不是多条线,如果query查询出来的是多条线,absent_over_time永远无法返回数据,断点检测也永远不会触发。

如上图,当tao_metrics_frp_heartbeat{frp="10350"}断点的时候,absent_over_time函数开始补点,所以配置报警规则后,可以及时检测到机器断点的情况。

当label匹配出多条线时,absent_over_time函数永远不返回数据。


如何降低宕机报警的误报频率?

降低误报频率可以从以下几个方向入手:

  • 提高目标集的准确性:如果ip:10.58.99.166的机器不存在,配置absent_over_time(heartbeat{ip="10.58.99.166"}) 这条规则是一定会触发报警的,所以要提高10.58.99.166是否存在的准确率。可能听起来很可笑,10.58.99.166这种基础数据怎么可能会出错呢。 现实情况是,很多目标集并不使用物理机、虚拟机的ip来作为机器心跳的唯一标识符,比如在K8S集群中,我们可能使用cluster+namespace+deployment+pod+container_name+port的多label形式来定位某个具体服务,K8S中的container销毁情况非常频繁,因此如果要判断某个端口是否存在,就需要及时拿到多label的变化情况,从而生成对应的报警规则。
  • 使用前置规则来进行排除: 举个例子,如果10.58.99.166这个ip在lf机房下,而我们的网络丢包指标network_packets_loss 是从外部探测的,那么在网络丢包率为100%时(相当于专线断开),应当排除机器的宕机情况(因为监控数据此时也无法上报),在MetricsQL中可以使用absent_over_time(heartbeat{ip="10.58.99.166"}) ifnot (network_packets_loss{dc="lf"} == 1) 这条规则来实现(if语句是MetricsQL中额外实现的,原生PromeQL不支持)
  • 降低转发过程带来的数据延时误报情况:合理配置规则中的for和keep_firing_for等字段,更好地过滤掉短暂的网络延迟导致的指标尖峰。