基于kafka和prometheus的无线APM报警系统设计和实现

2024-02-16 18:10

本文主要是介绍基于kafka和prometheus的无线APM报警系统设计和实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基于kafka和prometheus的无线APM报警系统设计和实现

移动APP是当下的主流。公司有很多业务线,有大量的APP。为了能够实现对这些APP性能的监控,为无线开发、测试人员提供性能诊断和分析工具,公司自行开发了无线APM系统。
我们的APM系统设计是这样的
![avatar][apmbase64]
无线APM系统通过移动端的SDK收集性能数据并上报到无线服务后端。各业务方可以通过无线控制台,查看经过聚合之后的性能数据。但是,这仅仅只能查看到各种性能数据过去的趋势。有时候业务方会比较关心实时数据有没有超过阈值,比如,过去5分钟之内某个地域的的网络请求时间均值是否超过了某个值。基于此类需要,需要开发APM的告警功能,当指定的性能指标超过了指定的阈值时,向订阅告警的业务方以邮件等方式发送通知。在研发告警功能的过程中,前后考虑了多种方案。

通过执行定时任务

我们无线端的APM数据收集之后最终存放在ClickHouse中。最初,
我们设想通过设计一系列定时任务,轮询ClickHouse中的数据,查询之后根据设定的条件进行聚合计算,与阈值比较,决定是否进行告警。这种方案如下图所示
![avatar][pollbase64]
这种方案,对于轻量级,逻辑简单的指标监控,这个方案是能满足需求的。但是,如果业务复杂,告警涉及的规则就必须通过程序代码实现,无法通过标准化的SQL查询实现。而且,告警监控功能是类似于“滑动窗口”式的,简单的轮询并不能完全满足这种需求。这将造成的后果就是:每添加一个业务数据的监控告警都需要耗费一定的开发资源,而业务使用方也无法进行自定义的告警配置。
鉴于自行开发定时任务的方案有以上缺点,所以我们最终没有采用这个方案。而是继续研究以下介绍的方案。

通过Grafana的Alert功能

如前所属,我们的apm性能数据是保存在ClickHouse中的。而对这些数据的聚合展示,则是通过Grafana。Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示,并及时通知。
Grafana天生具有Alert功能。在grafana的dashboard点击那个小铃铛,就可以创建一个alert。如下图所示
avatar
这里可以配置规则的名称,触发规则的条件(condition),持续多久之后再出发告警(for)。可以配置告警的接受者,以及告警信息的内容。总体来说,方便好用,而且基本能够满足日常的监控告警需求。grafana的告警配置详细介绍可以参考官方文档:grafana告警。
但是,这对我们来说,有一个问题:虽然我们的各种图表是用Grafana生成的,但是这些图表我们是通过链接内嵌进我们的控制台的。告警功能,我们也需要给业务方提供在控制台的配置入口,可以配置告警条件等参数。Grafana可以提供了HTTP的API,可以对dashboard进行配置,包括Alerting功能。其本质是通过一个大json配置dashboard的各个属性。具体可以参考Grafana HTTP API一切看着很美好,似乎沿着这条道路我们就可以实现美丽的目标了。但是,Grafana的告警功能,支持以下数据源:Graphite, Prometheus, InfluxDB, Elasticsearch, Stackdriver, Cloudwatch, Azure Monitor, MySQL, PostgreSQL, MSSQL and OpenTSDB。呃,前面说过,我们的数据源是ClickHouse,所以,据说有的版本Grafana已经支持ClickHouse数据源的告警了,但是,我们公司的版本目前还不行。所以,这个方案也只好作罢。这个方案的构想是这样的
avatar

通过prometheus直接查询Clickhouse

因为我们的数据都是存储到Clickhouse中的,而 Clickhouse 又具备了足够强大的查询聚合能力,因此,最初我们设想能够使用类似存储过程的方式,通过在 Clickhouse 中添加持续进行的 SQL 运算,并结合某种回调触发告警。然而,Clickhouse 本身并不支持存储过程。我们所能做的,是开发一个独立的服务,持续不断从 Clickhouse 中查询业务数据并进行规则匹配。这么做,似乎又回到了老路上,不可取。
于是,换一种思路,既然一个独立的监控告警服务不可避免,那么开源世界中有没有这么一种引擎可直接加以应用呢?经过调研,我们发现 Prometheus是一个绝佳的开源解决方案。Prometheus 最初是由 SoundCloud开发,2016年加入云计算基金会(CNCF),成为 Kubernetes 之后的第二个托管项目。Prometheus 本身被设计为一个高性能的时序数据库,可拉取以标准化形式呈现的数据并进行存储,同时实现了一种称为 PromQL的查询范式,内置数十种聚合算子。此外,Prometheus 还有一个伴生的告警管理组件 AlertManager,可用于管理 Prometheus 发出的告警,并将告警信息分发至相应的接收通道。
最开始我们的设想,以 Prometheus 标准化导入数据的方式,开发Exporter从 Clickhouse 向 Prometheus 同步数据。由于 Prometheus 本身接收数据采用的是拉取的模式,因此这期间涉及到拉取频率、拉取时效等问题,并且不同的数据集照样需要通过在 Exporter 中添加代码才能进行导出。这种数据同步算不上非常完美。
这种方案的架构如下图
avatar

通过KSQL+prometheus的方式

如上所属,prometheus已经为我们提供了完善的监控告警机制。如果我们能够解决前一方案的数据实效性的问题,问题的解决将会更趋于完美。而我们的数据,在到达服务端之后,首先是写入kafka,然后再被Clickhouse消费。如果我们能够针对Kafka中的流数据进行监控,则能很好的解决监控实时性的问题。而Kafka恰恰提供了相应的功能和工具,就是KSQL。
KSQL是一个用于Apache kafka的流式SQL引擎,KSQL降低了进入流处理的门槛,提供了一个简单的、完全交互式的SQL接口,用于处理Kafka的数据,可以让我们在流数据上持续执行 SQL 查询,KSQL支持广泛的强大的流处理操作,包括聚合、连接、窗口、会话等等。
这样,Kafka中原来进入Clickhouse的数据流不变,我们同时增加了KSQL对Kafka中的数据进行一次聚合,然后通过exporter打入prometheus,再通过prometheus的PromQL对这些数据进行二次聚合,并且针对不同的告警规范编写告警程序,并且根据聚合的结果向AlertManaer发送消息。
以下是这个方案的架构图
avater

总结

通过以上步骤,我们可以配置绝大多数业务数据的监控规则,利用 Prometheus 的算子,我们甚至可以对某些维度的数据进行预测型监控。但不可否认的是,目前 Prometheus和KSQL 无论是查询语言或是告警规则的配置,都有一定的学习门槛。我们后续要做的是,开发更细力度的告警规则,满足业务方多维度的监控告警需求。

通过prometheus直接监控ClickHouse

通过KSQL和promQL

这篇关于基于kafka和prometheus的无线APM报警系统设计和实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/715294

相关文章

pandas中位数填充空值的实现示例

《pandas中位数填充空值的实现示例》中位数填充是一种简单而有效的方法,用于填充数据集中缺失的值,本文就来介绍一下pandas中位数填充空值的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是中位数填充?为什么选择中位数填充?示例数据结果分析完整代码总结在数据分析和机器学习过程中,处理缺失数

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持

Pandas使用AdaBoost进行分类的实现

《Pandas使用AdaBoost进行分类的实现》Pandas和AdaBoost分类算法,可以高效地进行数据预处理和分类任务,本文主要介绍了Pandas使用AdaBoost进行分类的实现,具有一定的参... 目录什么是 AdaBoost?使用 AdaBoost 的步骤安装必要的库步骤一:数据准备步骤二:模型

使用Pandas进行均值填充的实现

《使用Pandas进行均值填充的实现》缺失数据(NaN值)是一个常见的问题,我们可以通过多种方法来处理缺失数据,其中一种常用的方法是均值填充,本文主要介绍了使用Pandas进行均值填充的实现,感兴趣的... 目录什么是均值填充?为什么选择均值填充?均值填充的步骤实际代码示例总结在数据分析和处理过程中,缺失数

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾

python实现svg图片转换为png和gif

《python实现svg图片转换为png和gif》这篇文章主要为大家详细介绍了python如何实现将svg图片格式转换为png和gif,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录python实现svg图片转换为png和gifpython实现图片格式之间的相互转换延展:基于Py

Python利用ElementTree实现快速解析XML文件

《Python利用ElementTree实现快速解析XML文件》ElementTree是Python标准库的一部分,而且是Python标准库中用于解析和操作XML数据的模块,下面小编就来和大家详细讲讲... 目录一、XML文件解析到底有多重要二、ElementTree快速入门1. 加载XML的两种方式2.

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组