创业公司技术体系建设 -APM

用户头像
星际行者
关注
发布于: 2020 年 08 月 02 日
创业公司技术体系建设-APM

APM被形象的称为应用医生,做为前文的后续,本文将详细介绍一下公司APM架构的演进过程。



一、1.0版架构



1.0版的架构中,主要通过应用改造集成一个jar包完成metrics采集,通过prometheus收集后,根据预设告警规则发送告警通知。整体的特点是:

  1. 应用需做改造,应用中集成apm-client.jar,prometheus周期性轮询/prometheus接口获取程序运行时状态。

  2. 监控配置在prometheus的配置文件中,运行时修改不方便。

  3. 告警接收人配置在alertmanager的配置文件中,运行时修改不方便。

  4. 只能采集cpu、memory、接口响应时间等metrics指标,采集不到trace。

  5. 应用必须包含web环境,否则无法通过/prometheus接口获取程序运行时状态。

  6. apm-client对程序性能几乎无影响。



二、2.0版架构

为了能够实现trace收集、运行时修改告警规则、尽可能无侵入,先后调研了PinPoint、Skywalking、Elastic Apm等几个通过Agent方式进行应用监控的Apm工具。



Pinpoint部署过于复杂,需要Hbase环境,首先被排除。Skywalking不能运行时修改告警配置也被排除在外(6.5.0之后可以)。Elastic Apm经过调研后也无法满足我们的要求。除此之外,Trace类的APM工具一般都根据Http状态码判断请求成功还是错误,但公司很多遗留的项目中确存在这样一种问题,接口内部已经出现错误,但确仍然返回http status code 200,在返回值中自定义了其他错误码,这样的写法导致了Trace类的APM工具无法判断接口返回是否正常。



public class Sample {
AppResponse getInfo() {
AppResponse ret = new AppResponse();
try {
// ...
// ret.setData()
ret.setCode(0);
}catch(Exception ex) {
ret.setCode(-1);
ret.setMsg(ex.getMessage());
}
return ret;
}
}



综合来看,无论哪个APM工具都不能满足我们的需求,需要定制开发,最初希望通过修改Skywalking来实现我们的需求,但很遗憾按照官方文档没有编译成功,最终我们通过修改Elastic Apm来完成公司的APM开发。2.0版的整体架构如下:



上文提到要解决运行时修改告警配置、判断接口返回是否成功这两个问题,对于运行时修改告警配置,我们开发了一个独立的Alert告警系统,并参考PromQL使用Antlr实现了语法解析器,周期性查询ElasticSearch来判断是否有异常发生。比如:



avg(dubbo{appname="qdp-polaris-server"} by interface range 5m) > 2000

计算5分钟内qdp-polaris-server系统各个dubbo接口的平均响应时间,如果超过2000ms则产生报警。 相当于SQL

select avg(响应时间) from table where timestamp between now() - 5m and now() group by dubbointerfacename



avg(http{appname=“qdp-polaris-server”, url ~= “.xxx.”} range 5m) > 2000

计算5分钟内qdp-polaris-server系统http接口名称匹配正则表达式.xxx.的接口平均响应时间,如果超过2000ms则产生报警。



avg(jvm.memory{appname="kafka-connect-platform-web"} by ip range 5m) > 1024

计算5分钟内kafka-connect-platform-web系统各实例jvm堆内存利用率,如果超过1024MB则产生报警。 相当于SQL

select avg(heap memory) from table where timestamp between now() - 5m and now() group by ip



对于判断接口返回是否成功这个问题,我们采用变通性办法解决,在程序中使用AOP拦截接口调用,通过自定义指标来记录接口返回是否成功,不在通过http status code进行判断。比如通过在程序中记录ERROR或者其他关键字来实现。



count(event{appname="qdp-skyline-web", keyword ~=".ERROR."} range 5m) > 5

计算5分钟内qdp-skyline-web系统LOG日志中匹配.ERROR.的总数,如果超过5次则产生报警。 相当于SQL

select count(1) from table where timestamp between now() - 5m and now() and message ~= “.ERROR.



基于Agent方式的APM有一个比较明显的缺点,只能根据用户的请求情况来判断系统是否正常,不能先于用户发现问题。为了解决这个问题,最初我们想使用Elastic HeartBeats进行接口主动探测来触发APM告警,后来在QA同学的建议下,我们用HttpRunner编写用例主动进行探活,用例开发的工作由QA同学来做。



三、总结

目前我们的APM工具仍然在进化开发过程中,告警量太多导致漏掉重要的告警信息也是一个要考虑的问题,目前我们采用类似AlertManager的方法过滤重复告警。





后续希望通过AI算法合并告警消息降低告警数量,以及引入CEP对告警事件做关联分析处理。




系列文章

一、创业公司技术体系建设

二、创业公司技术体系建设-CI/CD

三、创业公司技术体系建设-APM



发布于: 2020 年 08 月 02 日 阅读数: 266
用户头像

星际行者

关注

编程多年依旧热爱。。。 2019.03.28 加入

还未添加个人简介

评论 (1 条评论)

发布
用户头像
Pinpoint部署过于复杂,需要Hbase环境,首先被排除。这比自己开发一个APM还难啊?
2020 年 08 月 03 日 12:02
回复
没有更多了
创业公司技术体系建设-APM