作者:谦
本文为原创,转载请注明作者及出处
随着分布式系统架构的普及,系统越来越复杂,常常被切分为多个独立子系统并以集群方式部署在数十甚至成百上千的机器上。为掌握系统运行状态,确保系统健康,我们需要一些手段去监控系统,以了解系统行为,分析系统的性能,或在系统出现故障时,能有能力发现问题、记录问题、定位问题。也可以根据监控数据发现系统瓶颈,提前感知故障,预判系统负载能力等。
因此微盟 APM 系统应运而生,在微盟各业务线投入时候后,微盟各个业务线的小程序的公众号的流量也百万级别提升。之前 APM 系统的主要功能是进行日志、打点、报错等信息的采集和汇总,并以调用链的形式展现出来,方便开发、运营人员直观查询并根据报错、耗时等性能指标来排查异常或进行功能点优化。但随着流量的不断提升,另一个课题摆在了面前。在发现错误或者异常行为的情况下,如何能够在第一时间得知这样的情况并作出应对,故我们基于APM 系统打造了告警能力。
以上是我们的整体设计流程图,在我们对 APM 进行优化后,我们引入了 Ckafka,利用消息队列的高吞吐、低延迟的特点,达到更高的消息处理速度。基于 Ckafka,我们将告警设计成为一种数据消费的过滤条件。原因是因为初始数据发送至 Kafka 的时候有可能是进行过压缩等处理,故需要在消费者层面进行数据处理后才能存储至 Elasticsearch。所以我们基于这样的架构,在消费者端增加了一个数据筛选流程用于处理告警规则的判断。
不同于利用 Job 的设计,使用筛选条件的模式需要将过滤规则尽可能的扁平化,同时也更契合 ES 的数据格式,可谓一举两得。故我们会对用户自定义的告警格式进行展开,使之和数据上报至 ES 的格式保持一致,最后使用 Hash的方式直接筛选数据,时间复杂度为O(1),经测试对数据消费基本不会产生影响。
由于告警基本都是以频次来计算是否触发阀值,故我们采用了类似 rate-limiter 的令牌桶算法来计算触发告警策略的次数,当超过预定阀值之后即判断满足该条告警策略。而 rate-limiter 在分布式的应用中一般都会使用 Redis 在进行数量统计,故我们在告警策略/告警规则的变更中也一样使用了 Redis 来进行 Pub/Sub,所有在 APM 上的告警操作能瞬间同步到所有的 Consumer上并产生效用,不会存在延时,立即起效。
如下图所示,用户首先需要在APM系统中创建一条报警规则:
用户可以在规则中选择:
所监听的服务
产生的告警级别
抑制时间(告警的间隔)
发送告警的渠道(企业微信、邮件、短信等等)
告警接收人 (单人/用户组)
告警能力是接入了公司自研的虫洞平台,告警接收人以及用户组也是来自虫洞的数据
完成规则创建之后,接着用户需要对该条规则进行补充,即如何才能触发此条规则完成告警,那么就需要添加告警策略了。
何为告警策略?顾名思义就是告警规则的判断依据,只有满足了所有或者任一策略,该条告警规则才会真正对接受人发起告警。
告警策略的主要由以下几部分组成:
间隔:时间间隔
阀值:即时间间隔单位内满足策略的次数
过滤器:具体过滤的条件,主要为采集数据内的一些属性
操作符:对阀值的补充,是大于还是大于等于
是否为平均值
以上条件即约束了在固定时间间隔内满足过滤器内条件并超过阀值的数据,即会触发此条告警策略。
举个例子,让我们来新建一条策略:
上面这条策略约束了若5分钟内满足过滤器条件的数据,即「error = 1」出现的平均值超过10条,即命中此条策略。
新建或者更新完策略后,会通过 Redis 的 pub/sub 功能告知 kafka-consumer ,在 consumer 中会根据该报警策略生成新的过滤规则,在消费数据中进行过滤判断,若触发过滤条件则通过令牌桶算法(基于 Redis )记录触发次数,从而保证在分布式的架构中也能完成阀值统计,一旦触发阀值后,则会进行对应的告警。
由于过滤器中的值为用户上报数据中的部分字段,该字段的高度自由化,方便用户自定义监听维度。故可以定义出各种满足用户需求的告警维度,例如:
报错频次
卡顿频次
页面数据访问频次
某些接口的调用频次
而在整个告警规则中,基于一个或若干策略策略的触发,才会正真产生一条告警数据。根据该条产生的告警数据内配置的告警对象(人/用户组)以及告警方式(企业微信/邮件/短信等)进行精准告警。
以上就是微盟 APM 告警系统的整体架构以及实现,感谢您的阅读,我们下次再见。