1 背景
转转的推送系统为自研产物,实现过程简述为:对外提供一个接入层,以多次MQ转发形式进行多系统交互,内部包括:推送内容过滤、免打扰策略、厂商通道分发等逻辑,最终发起http请求至厂商通道,推送至设备,如图1所示。一条Push经过的逻辑节点众多,业务侧同学经常反馈Push收不到。每次收到反馈,都需要对链路中的每个集群进行排查,费时费力,亟需一种快速定位问题的方式,解放人力。
图1 转转推送系统-推送流程
2 idea的诞生
在调用链路层面,一次接口调用中,traceId贯穿整个调用链路,该能力由Radar(自研能力,负责埋点的生成等)+ Zipkin实现。当Push发送失败时,一定会在某个逻辑节点终止,如果我们可以将正向逻辑节点、异常逻辑节点以可视化的方式呈现出来,以traceId作为查询问题的线索,则可以在图中快速定位问题原因。
在数据采集方向上,对数据上报有严格的耗时、低性能开销要求。Prometheus监控体系的QPS在千万级别,耗时为纳秒级,内存占用和资源消耗都相对较小,主要取决于标签的数量,标签越多,内存占用越多。若采用traceId作为查询条件(对应Prometheus中的一个标签),可以通过抽样、限制收集的环境,即:只在测试、沙箱环境收集,降低对内存等资源的消耗。
以这两个层面为出发点,Grafana动态视图与我们诉求不谋而合。
3 什么是动态视图
动态视图,即:Flowcharting,是Grafana的一个插件。该插件借助在线图形库draw.io绘制、展示复杂图表。draw.io支持的图表包括:技术架构方案(Legacy、Cloud、Azure、AWS、GCP、Kubernetes、Terraform)、UML方案、工作流等。
可以用这个插件动态填充数据、自定义数据与图表的交互,它可以/支持:
- 监视状态和性能
- 与图表交互
- 根据数据或状态更改显示的对象
- 向对象添加链接
- 充分利用变量修改形状、颜色、链接、下载路径等
- 支持正则表达式进行匹配和替换
附官方动态视图样例,如图2所示。
图2 官方Grafana动态视图样例
4 构建看板
4.1 绘制视图
我们将一条Push经过的每个逻辑节点绘画出来,如图3所示。上方的绿色底色节点为正向节点,每个正向节点正下方对应一些异常节点,即:图中的土黄色节点。多个正向节点之间用箭头串联起来。此外,所有节点都定义了一个状态码,用来唯一标识该节点。节点状态码释义放在了最右侧的灰色底色节点中,点击该节点可以进入状态码说明在线文档。
图3 转转推送系统-链路流程图
4.2 上报数据
在公共jar包中定义一个Counter,该Counter中包含了两个标签:nodeName、traceId。其中,traceId对应视图中每个节点的名称。
private static final Counter NODE_COUNTER = Counter.build().name("push_link_graph_node_monitor").help("push链路节点监控").labelNames("nodeName", "traceId").disableAutoCreateGraph(true).register();
此外,在jar包中提供上报方法,供各服务上报数据使用。
public static void reportNodeInfoStrWithTraceId(String nodeName, String traceId) {
try {
if (StringUtils.isBlank(traceId)) {
traceId = com.bj58.zhuanzhuan.radar.util.RadarUtils.getTraceId();
}
NODE_COUNTER.labels(nodeName, traceId).inc();
} catch (Exception e) {
// DO NOTHING
}
return;
}
最后,在业务代码中上报埋点数据,如图4所示。
图4 上报埋点数据
4.3 创建Grafana看板
新建一个Grafana看板如图5所示。
图5 创建Grafana看板
点击《设置》按钮,完善基础信息、设置变量,如图6所示。
图6 设置按钮图示
基础信息的填写如图7所示,基础信息包括:看板名称、看板标签(可用来标记看板所属的部门信息)、看板数据的时间查询条件等。
图7 完善看板基础信息
设置变量如图8所示,该变量用作后续的数据源召回条件。变量的类型支持:即时手动输入、实时数据源、常量等等。这里将traceId设置为:即时手动输入类型。
图8 设置变量
4.4 将图导入Grafana
在已绘制好的流程界面中,选中《其它》tab,勾选其中的《编辑绘图》选项,如图9所示。然后复制XML内容到剪贴板中,如图10所示。最后将复制好的内容粘贴在FlowCharting看板内,如图11所示。
图9 编辑绘图
图10 复制XML内容
图11 粘贴XML内容
4.5 完善PromQL数据
这一步骤是书写查询语句,以获取视图中动态查询到的数据。在《Query》tab中填写PromQL、数据的图例维度,如图12所示。图例维度用作后续数据与图表的交互条件。
图12 完善PromQL与图例
对当前的推送场景来说,PromQL按照traceId聚合,图例使用nodeName。附,PromQL如下:
increase(push_link_graph_node_monitor{traceId="${traceId}"}[$__rate_interval])
如果对PromQL不了解,可以查阅参考资料中的第4点。
填写好的PromQL可以通过2种方式验证结果,如图13所示。
- QL验证方式一:打开页面右上角的《Table view》开关,可以观测到下方有查询数据展示出来。
- QL验证方式二:点击页面中部靠下的《Query Inspector》按钮,出现查询结果半层,半层中可以看到查询结果,如图14所示。当出错时,会给出提示信息,按提示排查即可。
图13 QL验证方式
图14 Query Inspector半层
4.6 定义Mapping
这一步骤是定义数据与图表的交互。Mapping包括:
- Color/Tooltip Mappings:将数据关联drwa.io XML元素,动态修改图的颜色、提示。如:订单数小于100单将图变红。
- Label/Text Mappings:将计算的数据展示到图上。
- Link Mappings:将图配置跳转链接,点击即可跳转。
- Event/Animation Mappings:用于将图的数据绑定事件,如:订单数小于100单,图的边框闪烁。
每个场景的使用方式可以参考官方网站,详见《参考资料》第3点,或点击每个页面元素右侧的问号查看帮助信息、样例,如图15所示。
图15 页面元素右侧的帮助信息
在推送场景中,我们使用Event/Animation Mappings,当数据满足一定条件时,图中的元素闪烁展示。首先我们配置数据的聚合方式与触发阈值,配置样例如图16所示。
图16 配置数据的聚合方式与触发阈值
其中lvl字段0值代表nodeName为21000的第一个不为空的数据大于等于0。后面会用到这个lvl值触发图形交互。
接下来,我们配置图形闪烁的条件,如图17所示。点击红色框中的《链接》按钮,然后在左侧选中要关联的页面图形元素,对应本图中的左侧蓝色框内容。选中之后,该元素的唯一标识会出现自动填充在右侧蓝色框中。之后,在黄色框里选择lvl的值,即我们刚刚设置的lvl为0这个值,代表当满足该条件时,元素会出现动效。最后在绿色框中设置动效效果为闪烁。
图17 图的数据绑定事件示例
以此类推,给页面上每个元素设置数据交互效果。
5 成果与收效
5.1 成果
通过draw.io绘制出含有Push链路中每个逻辑节点的视图,然后在Grafana上构建数据交互规则,将推送系统链路以可视化的方式呈现出来。
当我们拿到一个traceId后,输入到搜索框中,Grafana自动获取到数据,触发数据交互,高亮每一个逻辑节点,如图18所示,非常直观。
图18 推送系统动态视图演示
当异常节点高亮时,业务侧同学可以根据状态码查看说明文档,找出对应的解决方案,如图19所示,该图表明是苹果APNs通道返回了状态码为400,且原因为BadDeviceToken。
图19 推送系统动态视图-链路异常case
我们可以在图中灰色节点的在线文档链接中找到解决方案,如图20所示。
图20 推送系统APNs异常状态码释义
5.2 收效
在动态视图出现之前,人均排查时间为0.25小时以上,询问频率为每天N次。有了动态视图,业务侧同学基本能够根据动态视图定位到异常原因,实现自助解决问题,没有再询问过(排除服务异常的case,需要人工再次介入),极大降低了人力成本的投入。
6 推广
只要你的服务或者业务,可以用流程图绘制,都可以通过本文的方式构建出一张动态视图,以可视化方式展现逻辑,帮助你快速定位正向、异常逻辑节点,减少排查问题过程中的人力投入。
欢迎大家在评论区留言,也可添加微信号:zpc_1994
,进一步交流。
7 致谢
感谢架构部伙伴建新(王建新)同学、赵浩同学的答疑解惑,帮助我们深入了解数据采集、动态视图构建相关的原理,为最终的技术选型提供了有力的理论支撑。
8 参考资料
[1] 孟维道.转转Push系统设计及架构演进,2023
[2] 苑冲.Prometheus+Grafana:转转如何打造开箱即用的一体化监控系统?,https://mp.weixin.qq.com/s/uSgAAsIqFcKf9jPNKH7sOw
[3] flowcharting-repository,https://algenty.github.io/flowcharting-repository/
[4] 初识PromQL,https://www.topgoer.cn/docs/prometheus/prometheus-1ccta9bf6ibdq