监控界的最强王者,没有之一!(2)

简介: 监控界的最强王者,没有之一!(2)

Dog 简介


下面是 DOG 的架构图,客户端将消息投递给 Kafka,由 dog-server 来消费消息,存储用到了 Cassandra 和 ClickHouse,后面再介绍具体存哪些数据。


11.png


1、也有 APM 系统是不通过消息中间件的,比如 Cat 就是客户端通过 Netty 连接到服务端来发送消息的。


2、Server 端使用了 Lambda 架构模式,Dog UI 上查询的数据,由每一个 Dog-server 的内存数据和下游储存的数据聚合而来。


下面,我们简单介绍下 Dog UI 上一些比较重要的功能,我们之后再去分析怎么实现相应的功能。


注意:下面的图都是我自己画的,不是真的页面截图,数值上可能不太准确


下图示例 transaction 报表:


12.png


点击上图中 type 中的某一项,我们有这个 type 下面每个 name 的报表。比如点击 URL,我们可以得到每个接口的数据统计:


13.png


当然,上图中点击具体的 name,还有下一个层级 status 的统计数据,这里就不再贴图了。Dog 总共设计了 type、name、status 三级属性。上面两个图中的最后一列是 sample,它可以指引到 sample 视图:


14.png


Sample 就是取样的意思,当我们看到有个接口失败率很高,或者 P90 很高的时候,你知道出了问题,但因为它只有统计数据,所以你不知道到底哪里出了问题,这个时候,就需要有一些样本数据了。我们每分钟对 type、name、status 的不同组合分别保存最多 5 个成功、5 个失败、5 个慢处理的样本数据。


点击上面的 sample 表中的某个 T、F、L 其实就会进入到我们的 trace 视图,展示出这个请求的整个链路:


15.png


通过上面这个 trace 视图,可以非常快速地知道是哪个环节出了问题。当然,我们之前也说过,我们的 trace 依赖于我们的埋点丰富度,但是 Dog 是一个 Metrics 为主的系统,所以它的 Traces 能力是不够的,不过大部分情况下,对于排查问题应该是足够用的。


对于应用开发者来说,下面这个 Problem 视图应该是非常有用的:


16.png


它展示了各种错误的数据统计,并且提供了 sample 让开发者去排查问题。


最后,我们再简单介绍下 Heartbeat 视图,它和前面的功能没什么关系,就是大量的图,我们有 gc、heap、os、thread 等各种数据,让我们可以观察到系统的健康情况。


17.png


这节主要介绍了一个 APM 系统通常包含哪些功能,其实也很简单对不对,接下来我们从开发者的角度,来聊聊具体的实现细节问题。


客户端数据模型


大家都是开发者,我就直接一些了,下图介绍了客户端的数据模型:


18.png


对于一条 Message 来说,用于统计的字段是 type, name, status ,所以我们能基于 type、type+name、type+name+status 三种维度的数据进行统计。


Message 中其他的字段:timestamp 表示事件发生的时间;success 如果是 false,那么该事件会在 problem 报表中进行统计;data 不具有统计意义,它只在链路追踪排查问题的时候有用;businessData 用来给业务系统上报业务数据 ,需要手动打点,之后用来做业务数据分析。


Message 有两个子类 Event 和 Transaction ,区别在于 Transaction 带有 duration 属性,用来标识该 transaction 耗时多久,可以用来做 max time, min time, avg time, p90, p95 等,而 event 指的是发生了某件事,只能用来统计发生了多少次,并没有时间长短的概念。


Transaction 有个属性 children,可以嵌套 Transaction 或者 Event,最后形成一颗树状结构,用来做 trace,我们稍后再介绍。


下面表格示例一下打点数据,这样比较直观一些:


19.png


简单介绍几点内容:


type 为 URL、SQL、Redis、FeignClient、HttpClient 等这些数据,属于自动埋点的范畴。通常做 APM 系统的,都要完成一些自动埋点的工作,这样应用开发者不需要做任何的埋点工作,就能看到很多有用的数据。像最后两行的 type=Order 属于手动埋点的数据。


打点需要特别注意 type、name、status 的维度“爆炸”,它们的组合太多会非常消耗资源,它可能会直接拖垮我们的 Dog 系统。type 的维度可能不会太多,但是我们可能需要注意开发者可能会滥用 name 和 status,所以我们一定要做 normalize(如 url 可能是带动态参数的,需要格式化处理一下)。


表格中的最后两条是开发者手动埋点 的数据,通常用来统计特定的场景,比如我想知道某个方法被调用的情况,调用次数、耗时、是否抛异常、入参、返回值等。因为自动埋点是业务不想关的,冷冰冰的数据,开发者可能想要埋一些自己想要统计的数据。


开发者在手动埋点的时候,还可以上报更多的业务相关的数据上来,参考表格最后一列,这些数据可以做业务分析来用。比如我是做支付系统的,通常一笔支付订单会涉及到非常多的步骤(国外的支付和大家平时使用的微信、支付宝稍微有点不一样),通过上报每一个节点的数据,最后我就可以在 Dog 上使用 bizId 来将整个链路串起来,在排查问题的时候是非常有用的(我们在做支付业务的时候,支付的成功率并没有大家想象的那么高,很多节点可能出问题)。


客户端设计


上一节我们介绍了单条 message 的数据,这节我们覆盖一下其他内容。


首先,我们介绍客户端的 API 使用:


public void test() {
  Transaction transaction = Dog.newTransaction("URL", "/test/user");
  try {
    Dog.logEvent("User", "name-xxx", "status-yyy");
    // do something
    Transaction sql = Dog.newTransaction("SQL", "UserMapper.insert");
    // try-catch-finally
    transaction.setStatus("xxxx");
    transaction.setSuccess(true/false);
  } catch (Throwable throwable) {
    transaction.setSuccess(false);
    transaction.setData(Throwables.getStackTraceAsString(throwable));
    throw throwable;
  } finally {
    transaction.finish();
  }
}


上面的代码示例了如何嵌套使用 Transaction 和 Event,当最外层的 Transaction 在 finally 代码块调用 finish() 的时候,完成了一棵树的创建,进行消息投递。


我们往 Kafka 中投递的并不是一个 Message 实例,因为一次请求会产生很多的 Message 实例,而是应该组织成 一个 Tree 实例以后进行投递。下图描述 Tree 的各个属性:


20.png


Tree 的属性很好理解,它持有 root transaction 的引用,用来遍历整颗树。另外就是需要携带机器信息 messageEnv。


treeId 应该有个算法能保证全局唯一,简单介绍下 Dog 的实现:{encode(ip)}-当前分钟{自增id}。


下面简单介绍几个 tree id 相关的内容,假设一个请求从 A->B->C->D 经过 4 个应用,A 是入口应用,那么会有:


1、总共会有 4 个 Tree 对象实例从 4 个应用投递到 Kafka,跨应用调用的时候需要传递 treeId, parentTreeId, rootTreeId 三个参数;


2、A 应用的 treeId 是所有节点的 rootTreeId;


3、B 应用的 parentTreeId 是 A 的 treeId,同理 C 的 parentTreeId 是 B 应用的 treeId;


4、在跨应用调用的时候,比如从 A 调用 B 的时候,为了知道 A 的下一个节点是什么,所以在 A 中提前为 B 生成 treeId,B 收到请求后,如果发现 A 已经为它生成了 treeId,直接使用该 treeId。


大家应该也很容易知道,通过这几个 tree id,我们是想要实现 trace 的功能。


介绍完了 tree 的内容,我们再简单讨论下应用集成方案。


集成无外乎两种技术,一种是通过 javaagent 的方式,在启动脚本中,加上相应的 agent,这种方式的优点是开发人员无感知,运维层面就可以做掉,当然开发者如果想要手动做一些埋点,可能需要再提供一个简单的 client jar 包给开发者,用来桥接到 agent 里。另一种就是提供一个 jar 包,由开发者来引入这个依赖。


两种方案各有优缺点,Pinpoint 和 Skywalking 使用的是 javaagent 方案,Zipkin、Jaeger、Cat 使用的是第二种方案,Dog 也使用第二种手动添加依赖的方案。


通常来说,做 Traces 的系统选择使用 javaagent 方案比较省心,因为这类系统 agent 做完了所有需要的埋点,无需应用开发者感知。


最后,我再简单介绍一下 Heartbeat 的内容,这部分内容其实最简单,但是能做出很多花花绿绿的图表出来,可以实现面向老板编程。


21.png


前面我们介绍了 Message 有两个子类 Event 和 Transaction,这里我们再加一个子类 Heartbeat,用来上报心跳数据。


我们主要收集了 thread、os、gc、heap、client 运行情况(产生多少个 tree,数据大小,发送失败数)等,同时也提供了 api 让开发者自定义数据进行上报。Dog client 会开启一个后台线程,每分钟运行一次 Heartbeat 收集程序,上报数据。


再介绍细一些。核心结构是一个 Map<String, Double>,key 类似于 “os.systemLoadAverage”, “thread.count” 等,前缀 os,thread,gc 等其实是用来在页面上的分类,后缀是显示的折线图的名称。


关于客户端,这里就介绍这么多了,其实实际编码过程中,还有一些细节需要处理,比如如果一棵树太大了要怎么处理,比如没有 rootTransaction 的情况怎么处理(开发者只调用了 Dog.logEvent(...)),比如内层嵌套的 transaction 没有调用 finish 怎么处理等等。


相关文章
|
设计模式 SpringCloudAlibaba 负载均衡
每天打卡,跟冰河肝这些项目,技术能力嗖嗖往上提升
前几天,就有不少小伙伴问我,冰河,你星球有哪些项目呢?我想肝你星球的项目,可以吗?今天,我就给大家简单聊聊我星球里有哪些系统性的项目吧。其实,每一个项目的价值都会远超门票。
153 0
每天打卡,跟冰河肝这些项目,技术能力嗖嗖往上提升
|
3月前
|
移动开发 Dart 前端开发
“移动开发新纪元!跨平台框架与原生性能激情碰撞,未来已来!一场技术融合的革命大戏,你怎能错过?”
【8月更文挑战第7天】探索移动应用开发的未来:跨平台框架与原生性能的融合
67 3
|
3月前
|
存储 分布式计算 大数据
大数据处理竟然这么简单?学会这几招,你也能在数据洪流中游刃有余,秒变数据大师!
【8月更文挑战第6天】面对海量数据,有效处理成为关键。本文介绍大规模数据处理的核心挑战及解决方案,涵盖分布式存储(如HDFS)和计算(如Spark)。通过示例代码展示HDFS文件读写及Spark数据处理流程。此外,还强调了数据质量、安全及合理资源配置的重要性,助您在数据海洋中洞察先机。
74 1
|
安全 Java 虚拟化
涅槃重生!字节大牛力荐大型分布式手册,凤凰架构让你浴火成神
从大型机到单体架构,从微服务架构到无服务架构,每一次架构模式的演进都是一次涅槃。每一个软件系统都是由大量服务构成的生态体系,个体服务的“死亡”和“重生”是整个系统能否持续可靠运行的关键因素。笔记从5个方面全面剖析了如何构建一个可靠的分布式系统,同时给出了Spring Boot、Spring Cloud、Kubernetes、Istio、AWS Lambda五种架构风格的样例工程。
|
数据采集 机器学习/深度学习 人工智能
国产框架MindSpore联合山水自然保护中心,寻找、保护「中华水塔」中的宝藏生命
国产框架MindSpore联合山水自然保护中心,寻找、保护「中华水塔」中的宝藏生命
|
消息中间件 存储 缓存
监控界的最强王者,没有之一!(3)
监控界的最强王者,没有之一!(3)
256 0
监控界的最强王者,没有之一!(3)
|
存储 Prometheus 监控
监控界的最强王者,没有之一!(1)
监控界的最强王者,没有之一!(1)
171 0
监控界的最强王者,没有之一!(1)
|
存储 分布式计算 监控
专访骨灰级开源爱好者吴晟:开源没有黑魔法,两年后泡沫将会破灭
在刚结束的 2020 年,国内先后有超过 11 家开源软件领域企业获得了新一轮的资本助力,融资纪录创下近年来开源赛道最高。开源的热潮,已然兴起。然而,当越来越多的资本、企业等产业界人士开始越来越关注开源之时,一些隐藏在开源光鲜外衣背面的阴暗,也随之而来。
376 0
专访骨灰级开源爱好者吴晟:开源没有黑魔法,两年后泡沫将会破灭
|
SQL 机器学习/深度学习 存储
三分钟了解大数据技术发展史
梳理下大数据技术发展
836 0