如何快速定位异常?去哪儿网根因分析实践攻略请查收~
作者介绍
梁成琰
去哪儿网 devops 开发工程师,目前在基础架构-基础平台团队从事 CICD、可观测性等相关工作,云原生 SIG 成员,专注于研发效能提升。
特征工程:选择合适的数据,并将数据数值化 模型训练:利用sklearn等工具训练决策树模型 基于训练结果做根因分析,或做新数据预测分析 针对分析的结果做校验和优化
api/listener:服务入口层,支持api触发分析以及listener监听报警消息触发分析 orchestration:分析编排控制层,负责控制整个分析过程以及控制整合分析结果 analyzer:具体的分析器,包括链路trace、运行时runtime、事件event、日志log、中间件middleware、以及可扩展的extender data processor:分析结果处理模块,对分析结果进行聚合、权重判定、剪枝、排序 feedback/learning:反馈及学习模块 base data:基础数据层,负责获取及聚合分析模块所需的各种数据,比如event事件、日志信息、报警信息、指标数据等
对于监听报警所触发的分析,trace 时间段的选择是个需要首先考虑的问题。时间段过短,有可能导致相关 trace 未查询到;时间段过长,就会包含过多的无用 trace。
我们的开发同学在配置报警时,都是对一段时间内指标数值进行阈值判定,比如3m>4(连续3分钟大于4),2%5m>7(5分钟内有2个点大于7)。因此我们会根据当前报警所设报警规则的时间段,再加一个特定的时间窗口(比如3分钟,在第一个点满足报警阈值时,异常便已经产生了,向前推一小段时间,以防止 trace 遗漏),作为查询时间段。
trace 筛选的核心思想是漏斗式的筛选,首先根据 trace 是否异常进行分类。qtracer 在记录链路的过程中,如果某次调用判断为超时,或者 http/dubbo 返回状态码异常,便会将此次调用标记为异常,并将 trace 标记为异常 trace。若筛选出的异常 trace 量级仍然很大(比如大于500),那么我们继续根据 trace 的相似度进行进一步的筛选。
对于非异常 trace,首先根据T值进行筛选,因为不同的 T 值,对应的业务场景也不同,调用链路也不同。对T值相同的 trace,根据相似度筛选出 n 条数据,为了提升相似度的判定速度,我们将图进行降维,根据特定的规则将图构建为字符串,转换为字符串的相似度算法。
但 qtracer 当前只能标记出调用超时、调用状态码等异常,对于调用的返回结果中的业务状态码并不会进行判断。因此某些无异常的应用,也是有可能导致此次问题。我们在重点关注异常 trace 的同时,也会以非异常 trace 作为辅助。对于非异常 trace,我们对当前报警所属应用节点下钻 n 层拓扑,拿到拓扑应用后,根据应用的报警浓度等策略进行异常应用判定。
runtime:运行时分析,主要包括应用的单机实例(kvm、容器、宿主机)分析、业务指标单实例分析、JVM 分析如 full gc 等 middleware:中间件分析,目前主要是应用相关的 mysql 和 redis 分析 event:事件/变更分析,目前主要分析的是发布、配置变更、压测等,事件分析支持按部门配置,每个部门都可以单独配置自己关注的事件类型 log:日志分析,通过 heimdall 的异常日志统计能力,筛选出一段时间内的同比环比超过配置阈值的异常类型;并以筛选出的 trace id,从 es 查询出的异常日志作为补充
pmp-check-mysql-status-pc:pxc 节点状态,告警说明 pxc 不可用 pmp-check-mysql-status-size:pxc 集群没有可用节点,业务无法访问 pmp-check-mysql-status-fc:pxc 集群触发流控,整个集群变慢甚至不可用 pmp-check-mysql-status-threads-running:mysql 线程异常,实例负载过高或者有慢查询导致堵塞 pmp-check-mysql-processlist:mysql 线程异常, 实例负载过高或者有慢查询导致堵塞 pmp-check-mysql-replication-delay:主从同步延迟 pmp-check-mysql-replication-running:主从同步失败 pmp-check-mysql-status-connect:连接数已满,无法连接 check_mmm:集群状态有问题,节点下线 pmp-check-mmm-vip:mmm 集群的 vip 连通性,告警说明 mmm 集群 vip 不通,业务无法访问数据库
q-check-redis-cpu-usage:redis cpu 告警 q-check-redis-memory-usage:redis 内存告警 q-check-redis-latency-port:redis 延迟告警,比如 redis 大 key 时有可能导致此报警
应用权重:
what:应用权重表示在整个调用链路中,当前异常应用影响报警/故障的概率的大小。
why:比如我们对多条异常trace进行分析,发现应用B多次被标记为异常应用,那么我们倾向于认为,是应用B大概率导致此次问题,计算得到的应用B的权重就会很高。又或者对于一条调用链路A->B->C→D,如果当前报警的是应用A,那么根据专家经验,应用B对A的影响要比应用C对A的影响要大,因此我们认为应用B的权重要比应用C要高。
how:目前应用异常权重分两部分计算,异常trace的应用权重通过trace归并计算,比如每重复出现一次,权重增加0.1等,并且异常应用也要综合考虑和当前报警应用的拓扑联通性以及连通层级。而对于非异常trace,主要是根据应用距离当前报警应用的距离计算,类似于欧几里德距离,距离报警应用越近,权重越高。
静态权重:
what:静态权重也就是经验权重,我们总结了2022年上半年的故障原因分布占比,来设置根因分析每个维度的权重比。
why:其实这种静态权重代表了去哪儿网自身的业务特点,比如因发布或者配置变更导致的故障占比50%,说明在去哪儿网发布或配置变更是一个相对比较危险的动作,如果再次发生故障,且我们在事件分析中定位到了异常应用有发布或者变更,那么我们就会倾向于认为这次问题大概率是此次发布或者变更导致的。
how:人为统计故障原因分布占比,并配置到应用配置中。需要注意的是,这个静态权重不是一成不变的,需要每隔一段时间,就根据新的数据调整一次。我们的反馈和学习模块,也会自动根据故障原因分布和用户反馈结果,进行静态权重的调整。
动态权重:
what:动态权重,我们也称为root case权重,根据各个原因的严重级别来对自身进行升级,以避免真正的根因被淹没掉。
why:静态权重只能是一个大概的推测,并且已经归一化了,起到的更多是default设置的作用,提供一些参考意义。比如一个报警或故障,我们分析出链路中某个异常应用有一些调用超时日志,且同时有mysql/redis实例连接失败,那么按照专家经验来看,mysql/redis实例连接失败是一个严重级别很高的原因,因此mysql/redis实例连接失败这个case,便可以自身升权。
how:目前动态权重主要是依靠专家经验,以及case的严重程度,比如磁盘使用率100%,IO使用率100%,DB/redis挂掉,CPU使用率超过90%等,都可以动态升权。
强弱依赖权重:
what:强弱依赖权重其实有些类似应用权重,强弱依赖里明确标明了,A应用的 m1接口依赖B应用的 m2接口是强依赖还是弱依赖,根据此信息可以断定,B应用的异常尤其是m2接口的异常对A应用尤其是A应用的m1接口影响的概率。去哪儿网强弱依赖关系,是通过混沌工程进行强弱依赖演练得到的。
why:强弱依赖是已经人为或系统标记了 A 应用到B应用是否是强依赖或若依赖,这是一个非常重要的信息,比如 A 同时依赖 B、C两个应用,但是根据强弱依赖信息,我们知道B应用对A应用是强依赖关系,而C应用对A应用则是弱依赖关系,那么当A故障时,我们同时发现了B和C两个应用此时都有异常信息,那么此时可以倾向认为B的异常导致了A故障,B的权重大于C。
how:目前强弱依赖标记的是接口维度,在根因分析过程中,根据trace分析拿到当前异常的接口,则可以根据API搜索当前应用的此API的强依赖,如果没有被标记,那么可以回归聚合,将接口维度的强弱收敛到应用维度的强弱,比如A依赖了B的3个接口,2个弱依赖接口一个强依赖接口,那么我们就可以认为B是A的强依赖,按照这种该逻辑来收敛应用级的强弱依赖,强依赖的权重大于弱依赖。
以上就是本次分享的所有内容啦!
最后,给大家带来一些岗位招聘信息。
你与驼厂只差一份简历的距离
快扫码投递吧