互联网APP监控即时报警解决初步方案

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xhpscdx/article/details/82289254

一,概要

  1. alarm的功能设计参考oneapm功能规划,下面将详细描述。
  2. 也参考开源skywalking,pinpoint等监控告警系统,确定流式计算是解决报警最好方案。

二,功能概要

1.报警策略
  1. 报警策略用来描述关联的监控对象与指标类型。
  2. 策略包括(总览属性,报警对象,通知对象,匹配条件)
字段 规则 业务描述
策略名称 唯一性, 代表一个报警策略
应用名称或集群名称 多选 参考onepam应该支持多选app。具体的监控对象
应用实例或集群节点 按类型多选 具体的监控对象实例
监控指标 字典表 web请求,JvM,jdbc等
监控维度项 字典表 关联监控指标所拥有的维度
何时可用规则 参考oneapm,具体意思指定时间段内规则是否生效。 增对时间段监控
等待时间 报警规则每分钟都在进行计算,当报警事件开启后且报警对象持续n分钟,一直处于严重或警告条件时,会触发报警持续事件。 避免连续收到大量通知。
  1. 疑问应用名称或集群名称是否需要多选,oneapm支持,对应op来说也需要支持多选。
  2. 等待时间:举个例子,对于一项叫“check out”的业务来说,假设你的等待时间设定的是30分钟,并且在13:00的时候产生了一个“严重”的报警,那么在30分钟之后的13:30才会进行新一轮的持续报警event,除非状态变为了“警告”或者报警已经被处理。假如在13:05“check out”业务的报警状态变成了“警告”,那么就会开始新一轮的报警等待,也就是说会在13:35进行“警告”的报警通知。
2.触发条件

broker


  1. 参考oneapm,多组匹配条件应该在一个时间窗口里,否则时间窗口无法控制。
  2. 对于触发条件可以定义两个等级,严重,警告。
字段 规则 业务描述
报警类型 严重,警告 代表event type
时间窗口 3,5,10,15,30,60 分钟可选 用于计算时间范围值
多条件关系 all,any
监控算法 平均值,至少一次,总是
运算符 大于,小于
报警阀值 关联监控指标所拥有的维度

3. 疑问?是否需要把监控维度项放在触发条件中选择,形成多个监控维度项匹配。

  1. 数据丢失告警
    • 警告条件中输入的分钟数至少要2分钟;严重条件中输入的分钟数要大于警告条件中输入的分钟数。
    • 我们只需要简单设计在n分钟内没获取data就告警。
3.告警事件

broker


  1. 通过page可以查询该策略产生的event通知记录,存储在mongodb中。
  2. 通道email通知事件。

三,数据库


broker
这里写图片描述


  1. 表alarm_strategy对应报警策略信息
  2. 表alarm_strategy_instance 对应的报警策略实例选择
  3. 表alarm_strategry_condition 触发条件

四,alarm架构结构图

1.介绍

broker
这里写图片描述


  1. 采用kafka stream来消费all metrics信息。移除以前的topic分配策略,采用kafka rebalance来自动管理instance。
  2. 本地Cache所有strategry信息,2分钟同步一次数据。
  3. kafka stream的FilterProcessor根据cache strategry过滤接收到message。
  4. ReduceProcessor的根据message及strategry计算匹配condition。如果满足则发送alarmEvent消息事件。

  5. alarmEvent消费处理器,根据strategry等待时间是否持久化并通知用户的告警。

2.疑问
  1. 需要明确对一个AppName一类metric消息是分散多个sentry实例,还是一个实例。这个对于ReduceProcessor聚合运算来说是前提。
  2. 目前的sentry使用大量localCache来存储聚合窗口结果。如果AppName一类metric消息分散多个实例,则不能达到一致。
  3. 目前每个metric消息是按照hashCode指定为kafka消息key的。能保证同一个AppName同一类metric消息是在一个sentry实例上。
    4.
"category": "http-metrics",

            String sourceAppName = entity.getAppName();
            String sourceHostName = entity.getHostName() + ":" + entity.getPort();

            // 搜索调用者id是否已存储
            Long sourceMetadataId = appMetadataManager.searchAppRecord(AppMetadataParseConstant.ROOT, MetadataTypeConstant.JAVA_APP, sourceAppName);
            Long hostId = appMetadataManager.searchAppRecord(sourceMetadataId, MetadataTypeConstant.INSTANCE, sourceHostName);
            metricMap.put("appName", sourceMetadataId);
            metricMap.put("hostName", hostId);
            metricMap.put(Constants.HASH_CODE, HashCodeUtil.getHashCode(sourceAppName));

猜你喜欢

转载自blog.csdn.net/xhpscdx/article/details/82289254