从分析 SkyAPM-dotnet 源码学习现代 APM 探针设计理念

前言

后端软件行业正经历着缓慢却又日新月异的改革,从SOA到微服务、从业务一体化到中台战略、从虚拟化到云原生,历史告诉我们,在技术上如果跟不上时代的变迁,就终将成为技术的弃儿。

2020年,整体技术的发展已经充分影响到后端软件工程师开发的方方面面,包括开发时的所想所写,代码构建、部署和发布的流程,以及后期维护、优化的方式。这背后的推动力说白了就是硬件的发展已经遇到了瓶颈,人们无法在硬件上获得更大突破,所有才有了追求软件行业大规模的积聚效益的动力。

本篇着重描述dotnet探针代码结构及基本原理,下一篇将描述Tracing在SkyWalking中的实现规范。

闲话不多说,回到主题,作为一个现代(ppt)后端软件工程师,若我们需要对我们运行的服务的性能有充分的了解,就离不开APM(Application Performance Monitoring)。APM有三个基本定义:

1、Metrics 指标性统计
比如说我们会去做一个服务的 TBS 的正确率、成功率、流量等,这是我们常见的针对单个指标或者某一个数据库的,这就是 Metrics 单指标分析。
2、Tracing 分布式追踪
这里提到的是一次请求的范围,也就是我们从浏览器或者手机端发起任何的一次调用,甚至我们可以再推广一点,是一次业务教育,比如说一次订购的过程,从浏览商品到最后下定单、支付、物流、最后交到我们的手上。这是一个流程化的东西,我们需要轨迹,需要去追踪。
3、 Logging 日志记录
我们程序在执行的过程中间发生了一些日志,会一帧一帧地跳出来给大家去记录这个东西,这是日志记录。
如果你做一个监控的产品, 你需要明确自己的定位,每个领域实际上要关心的事情是不一样的,而且这些领域之间会有交叉点。比如 Metrics 和 Logging 可能是之于某个指标的统计,但你通过日志的方式去做了一个搜集,最后统计了这些 Metrics 的信息,以及这些 Metrics 信息和对应的 Logging 的关系,那么你走的可能是 Metrics 和 Logging 之间的范围。如果你要去做 Metrics 和 Logging 中间的这些点,你需要清楚你是不是要付出这么大的代价。因为你每去占到这个圆中的一个部分,你的系统复杂度、内存的开销、后端的存储都需要付出相应的代价。随着指标数、内容的加入,你所要投入的研发技术难度也在逐步上升。

在几年前,我们可能会自己开发性能监控系统(造轮子

  • Metric监控我们可以有基于代码入侵的打点或者非入侵的agent,然后上报到Prometheus存储、最后用一套UI比如Grafana展现出来。
  • Tracing监控我们有Zipkin、jaeger以及今天的主角Apache Skywalking等
  • Logging利用ES来作存储查询,然后使用Kibana展示

SkyWalking也干了差不多的事情,只不过它是一套标准化的系统,他出现的意义就在于减少我们重复的开发工作(KPI又少了)。关于SkyWalking的数据核心 OAP(Observability Analysis Platform)我能力不够不作分析,今天我们来看看基于其规范的 dotnet 探针的设计思路。


源码结构

这个项目是一个实现优雅的core风格的项目,目录拆分、文件命名都有所考究,代码上整体都遵循依赖注入。

项目大体结构分为:

  • Core :探针核心启动逻辑,注册自己到OAP数据中心,对采集到的数据进行格式归一、采样及最后的上报工作
  • http://Agent.XXX :不同Host的agent输出,目前有 netfx、netcore 以及 general host三种
  • http://Diagnostics.XXX :不同的采集器实现
  • CLI :命令行工具
  • Transport :与OAP数据中心的传输协议层,目前数据上报都是用的gRPC来传输
  • Utilities:日志、依赖注入扩展、配置读取等

最后的产物就是名字叫http://SkyApm.Agent.XXX的几个dll,这几个dll根据各自所代表平台的特点,对不同的采集器进行了组合。

探针数据采集器的基本原理是:DiagnosticSource。

在 .NET Core 中使用 Diagnostics (Diagnostic Source) 记录跟踪信息​www.cnblogs.com图标

DiagnosticSource 实现了一个消息的生产者消费者模型,在某个地方触发消息,然后可以在任意地方接收。微软在很多官方库里都预留了性能打点,例如:HttpContext、HttpClient、SqlClient、EntityFrameworkCore等,还有gRPC、CAP、SmartSql等一些第三方库等也都提前留了打点。它们在开始做某件事、做完某件事、做错某件事的时候,都会对进程内触发一个消息,让我们可以通过 DiagnosticSource 消费到这个消息,然后就可以用它来记录某次事件的具体历史了,便是实现了tracing。

我们也可以为自己的库配适SkyWalking,但是要手动打点,向 DiagnosticSource 发送你的事件信息,然后扩展一个自己的采集器就可以了。

探针监听这些消息的关键代码就一句:

DiagnosticListener.AllListeners.Subscribe(_observer);

DiagnosticListener 即是 DiagnosticSource 的具体实现,这个_observer 参数即是探针所做的主要工作,我们利用它来监听消息,然后将数据发送到数据中心,它是一个 TracingDiagnosticProcessorObserver类型,这个类型维护了一组 Processors,这些 Processors 就是各个具体干活的采集器了。

private readonly IEnumerable<ITracingDiagnosticProcessor> _tracingDiagnosticProcessors;

它们都实现了一个简单的接口 ITracingDiagnosticProcessor

public interface ITracingDiagnosticProcessor
{
    string ListenerName { get; }
} 

实例分析

我们拿两个有代表性的 Processor 来研究:

  • HostingDiagnosticProcessor
  • HttpClientDiagnosticProcessor

https://github.com/SkyAPM/SkyAPM-dotnet/blob/master/src/SkyApm.Diagnostics.AspNetCore/HostingDiagnosticProcessor.cs

https://github.com/SkyAPM/SkyAPM-dotnet/blob/master/src/SkyApm.Diagnostics.HttpClient/HttpClientDiagnosticProcessor.cs

前者是AspNetCore请求管线的Processor,它内部监听了这些事件源:

  • Microsoft.AspNetCore.Hosting.BeginRequest
  • Microsoft.AspNetCore.Hosting.EndRequest
  • Microsoft.AspNetCore.Diagnostics.UnhandledException
  • Microsoft.AspNetCore.Hosting.UnhandledException

后者是http://System.Net下的通用httpclient,内部监听了这些事件源:

  • System.Net.Http.Request
  • System.Net.Http.Response
  • System.Net.Http.Exception

我们只要监听这些字符串代表的事件,就可以完整地拿到请求的上下文,有了这些上下文后,就可以产出一些标准的tracing信息,然后上报到数据中心。经OAP分析后,SkyWalking即可为我们展现出直观的 APM 信息,推荐读者可以自己动手在电脑上安装SkyWalking,加入探针后启动自己的服务,体验一下。

https://github.com/SkyAPM/SkyAPM-dotnet​github.com

 

 

完。

 

编辑于 01-20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值