cat 监控系统
cat(https://github.com/dianping/cat)是应用监控系统,支持的消息类型如下:
- Transaction 适合记录跨越系统边界的程序访问行为,比如远程调用,数据库调用,也适合执行时间较长的业务逻辑监控,Transaction用来记录一段代码的执行时间和次数。
- Event 用来记录一件事发生的次数,比如记录系统异常,它和transaction相比缺少了时间的统计,开销比transaction要小。
- Heartbeat 表示程序内定期产生的统计信息, 如CPU%, MEM%, 连接池状态, 系统负载等。
- Metric 用于记录业务指标、指标可能包含对一个指标记录次数、记录平均值、记录总和,业务指标最低统计粒度为1分钟。
- Trace 用于记录基本的trace信息,类似于log4j的info信息,这些信息仅用于查看一些相关信息
大致流程:
- 客户端初始化,拉取配置信息,主要包括路由、开关,采样率,之后定时刷新。路由是由一组IP组成,因为客户端是使用netty,所以需要自己做负载和高可用。
- cat客户端是用Context保存埋点消息,Context是维护在ThreadLocal中,Context里面有一个Stack变量,当开启一个Transaction 的时候埋点消息入栈,Transaction 结束时埋点消息弹出,结束后会被flush到一个队列中,另外一个线程从队列中读取数据,对数据处理后,再被丢入一个队列,之后数据发送模块从队列中读取数据,对数据编码后并上报数据。
- 服务端接收数据后并解码,解码后会将消息发送给Period,Period中有一个Map集合保存所有PeriodTask(其实是对应了MessageAnalyzer,MessageAnalyzer的含义参考下面),PeriodTask内部会有一个队列和一个MessageAnalyzer,Period会将消息发送给所有的PeriodTask,PeriodTask会将消息保存到队列,MessageAnalyzer会从队列中读取消息并解析。CAT目前有12个MessageAnalyzer,对于性能有要求的,单个MessageAnalyzer可以开启多实例,消息会被发送到多实例中的一个(根据domain hash)。
- MessageAnalyzer就是对MessageTree的具体处理。MessageAnalyzer有多个,每个作用各不一样,有的用于统计,有的用于保存。
我的注解版:
关于监控系统思考:
作为一个监控系统,第一原则就是不能影响业务系统,所以监控客户端肯定有降级策略和异步策略。
- 降级策略:可以使用配置系统,在必要的时候,关闭采集。
- 关于异步策略,可以采用内存队列保存消息
监控系统关于信息上报:
- 根据统计精度,可以选择实时上报,也可以选择定时上报(比如5秒上报一次,这里注意 要做下时间对齐)。
- 根据系统压力,可以选择全量上报,也可以选择采样上报,也可以初步分析合并后上报(比如对于调用量可以选择对5秒内的数据做一个累加后上报)。
另外一点最关键的就是监控系统的数据一定要全,有些公司iaas层监控用zabbix, 业务层监控用自己公司研发的, 异常报警系统还有一套单独的。链路跟踪用其他的,如果出了问题,查起问题来需要跨多个系统。最好是能够将如下数据打通:
- 硬件层:CPU,内存,网络,IO,网络状态、网络连通情况,负载情况,DNS,CDN情况
- 基础设施层:MySQL,redis,MongoDB,JVM,Nginx等,主要查看数据库主从延迟,调用量,线程数,数据库响应时间,慢SQL,JVM包括GC和内存情况,nginx的网络负载情况。
- 服务层监控: 调用量,耗时,响应时间等,这些监控可以在接口级别,也可以在方法级别,甚至代码块级别。
- 大服务层: 有多少服务,每个服务多少台机器,服务版本号,服务健康情况,服务链路
- 业务指标监控: metric, 交易量,注册用户。
- APP层监控:APP打开率,APP首页打开速度,APP崩溃指标。
- 系统发布事件,运维机器调整事件。这个主要是为了做异常排查的时候使用。
关于告警策略:
监控系统毕竟不能让人天天在那里守着,除了代码中抛出的异常报警,我们还可以
- 对数据本身进行监控,比如最大值,最小值,同比和环比的波动情况。
- 自定义规则,比如CPU大于某个阈值,内存小于某个阈值。 网络ping丢失,或者流量大于某个阈值。
- 利用机器学习进行时间序列预测。
关于异常快速分析和处理:
如果异常发生后都依靠人工去排查还是有些耗时的,监控系统应该还可以辅助技术人员快速发现问题,甚至直接解决问题。
- 系统应该可以快速聚合错误,比如分析error日志,聚合错误类型,快速定位到发生的错误类型。还可以根据链路日志,找出请求参数。根据参数可以快速在STG环境复现。 还可以根据IP做聚合,看异常是发生在一台机器上,还是多台机器上都有。还可以和运维事件关联,比如在发生异常之前,是否有其他依赖的系统发布。
- 对于某些异常,比如IO超过阈值,或者CPU超过阈值,根据定义的规则(比如: 异常类型为连接池拒绝错误, QPS环比增加30%, 且CPU整体利用率大于60% ) 可以调用发布系统,进行系统的横向扩展。