背景

随着支撑的内部业务系统越来越多,向着服务化架构进化,在整个迭代过程中,会逐渐暴露出以下问题。

  1. 传统依赖于应用服务器日志等手段的排除故障原因的复杂度越来越高,传统的监控服务已经无法满足需求。
终端--> Nginx --> IIS --> Asp.net 管道 --> [数据缓存]->[HTTP调用]->[DB读写]

在以上调用链路上,我们以往勉强能从 Nginx 日志中分析出 客户端调用时长,Nginx 调用API服务时长。
但是到了应用程序代码,对于[数据缓存]->[HTTP调用]->[DB读写]等操作,变成了链路调用黑盒。
  1. 在出现性能问题定位,也严重依赖高级工程师经验,定位困难,指标不明确。
  2. 在分析整个应用调用链路,不能清晰、直观的分析展现。

度量(Metrics),跟踪(Tracing),日志(Logging)

Logging,Metrics 和 Tracing 有各自专注的部分。

  • Logging - 用于记录离散的事件。例如,应用程序的调试信息或错误信息。它是我们诊断问题的依据。
  • Metrics - 用于记录可聚合的数据。例如,队列的当前深度可被定义为一个度量值,在元素入队或出队时被更新;HTTP 请求个数可被定义为一个计数器,新请求到来时进行累加。
  • Tracing - 用于记录请求范围内的信息。例如,一次远程方法调用的执行过程和耗时。它是我们排查系统性能问题的利器。

详细阅读,参考度量(Metrics),跟踪(Tracing),日志(Logging)

这三者的交集,才是对于我们分析应用程序运行状态及调用链路分析,有这直观重要的意义。

日志(Logging),可以使用ELK技术栈,解决我们的应用程序日志查询分析的大部分需求。

度量(Metrics),可以使用AppMetricsPrometheus 来满足一部分需求。

跟踪(Tracing),全链路的调用分析追踪,目前解决方案大部分也是商业解决方案,如Application Insights、OneAPM、听云、Datadog等,开源方案,如SkyAPM (.net core适用)

目前,针对 .net 平台下探针的解决方案进行调研,大部分是付费,开源方案大部分针对 .net core。

有没有一种可能,我们使用开源技术,搭建自己的全链路调用分析的解决方案,这是本篇博文需要探索的议题。

我们将带着以下几个问题,进行探索解决方案

  1. 我们基于什么标准规范来收集指标?
  2. 出于保护企业现有投资的情况下,我们需要针对Full Framework(.net Framework、.net core)下进行支持,也可以考虑公有云应用监控。
  • 代码级定位性能问题
  • 记录应用错误过程
  • 检测慢SQL语句
  • 检测外部调用API耗时
  • 检测调用外部HTTP请求耗时,请求信息记录
  • 请求/RPC 调用关系拓扑
  1. 基于什么架构来搭建,有哪些组件可用,能不能达到商业解决方案的相差无几的解决方案?
  2. 用什么的技术来实现?

跟踪(Tracing)标准 OpenTracking

OpenTracking 为监测提供了一组标准的框架无关、厂商无关的标准规范,这意味着开发者能够很方便的添加/切换跟踪系统

简单说,OpenTracking 提供了一组规范,也是分布式跟踪系统的标准的抽象,来解决不同的分布式追踪系统的API标准的不兼容问题。OpenTracing 是一个轻量级的标准化层,它位于应用程序/类库和追踪或日志分析程序之间。

更多关于 OpenTracing 数据模型的知识,请参考 OpenTracing语义标准

技术探索

分布式追踪系统,由追踪器(Tracker)、追踪信息收集代理(Agent)、追踪信息存储分析服务(APM Server)组成。

追踪器(Tracker):负责应用程序监控(代码级别执行时间、异常调用)

追踪信息收集代理(Agent):负责应用程序监控信息上报

追踪信息存储分析服务(APM Server):负责存储应用程序监控信息存储分析展示等服务

追踪器(Tracker)

代码埋点是实现Tracker重要一步。

如果在业务代码中实现追踪埋点,不但工程量大,而且代码入侵严重。

var tracker = Tracker.Instance;

using(var context = tracker.Begin())
{
context.SetSpan("name of span"); /// some business logic context.EndSpan(); tracker.Send(context); }

为了实现dotnet全平台下(Framework、dotcore)追踪,我们需要清楚C#代码是如何变成机器可运行的代码。

  • 第一步,C# 编译生成中间语言 IL
  • 第二步,中间语言IL 通过CLR的即时编译JIT,编译成Native Code

我们只能通过,在CLR即时编译 IL之前,修改已生成的IL,来实现代码埋点。这样以来,我们便可以轻松的实现零入侵业务代码。

如何实现修改已生成的IL ? 我们通过实现CLR公共语言运行时ICorProfilerCallback 中重写JITCompilationStarted 方法即可实现。

在dotnet core 下通过DiagnosticSource 实现,应用程序性能诊断

DiagnosticSource VS EventSource

  • EventSource,只支持Windows,主要记录可序列化的数据,被进程意外的消费。
  • DiagnosticSource,支持 .net core下,主要在进程内处理数据,可以支持非序列化的对象,比如HttpConext,HttpResponse。
  • 如果在 EventSource 中获取 DiagnosticSource 中的事件数据,可以通过 DiagnosticSourceEventSource 这个对象来进行数据桥接。

Further Reading

Dotnet全平台下APM-Trace探索的更多相关文章

  1. .NET平台下,关于数据持久层框架

    在.NET平台下,关于数据持久层框架非常多,本文主要对如下几种做简要的介绍并推荐一些学习的资源: 1.NHibernate 2.NBear 3.Castle ActiveRecord 4.iBATIS ...

  2. BEA WebLogic平台下J2EE调优攻略--转载

    BEA WebLogic平台下J2EE调优攻略   2008-06-25 作者:周海根 出处:网络   前 言 随着近来J2EE软件广泛地应用于各行各业,系统调优也越来越引起软件开发者和应用服务器提供 ...

  3. Windows平台下Oracle实例启动过程中日志输出

    Windows平台下Oracle实例启动过程中日志输出记录. 路径:D:\app\Administrator\diag\rdbms\orcl\orcl\trace\alert_orcl.log 输出内 ...

  4. Windows平台下Oracle监听服务启动过程中日志输出

    Windows平台下Oracle监听服务启动过程中日志输出记录. 日志目录:D:\app\Administrator\diag\tnslsnr\WIN-RU03CB21QGA\listener\tra ...

  5. Windows 平台下 LiteIDE 的安装和使用

    1. 安装 Go 语言并设置环境变量 参考博客<Windows 平台下 Go 语言的安装和环境变量设置>. 2. MinGW 的下载和安装 Windows 下的 Go 调试还需要安装 Mi ...

  6. Caffe介绍与测试及相关Hi35xx平台下caffe yolox的使用参考

    这一篇我大概讲讲Caffe框架下MNIST的实现与基于Hi35xx平台下caffe yolox的运用等,供大家参考 1.Caffe介绍与测试 caffe全称Caffe Convolutional Ar ...

  7. [转]Windows平台下Makefile学习笔记

    Windows平台下Makefile学习笔记(一) 作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译 ...

  8. Android平台下OpenCV移植与使用---基于C/C++

    在<Android Studio增加NDK代码编译支持--Mac环境>和<Mac平台下Opencv开发环境搭建>两篇文章中,介绍了如何使用NDK环境和Opencv环境搭建与测试 ...

  9. Windows平台下Git服务器搭建

    第一步:下载Java,下载地址:http://www.java.com/zh_CN/ 第二步:安装Java.安装步骤不再详述. 第三步:配置Java环境变量. 右键”计算机” => ”属性” = ...

随机推荐

  1. Linux中mongodb定时远程备份

    下载mongodb https://www.cnblogs.com/tartis/p/5291580.html mongodb定时备份文档 虚拟机报错要改BIOS 虚拟技术开启 进入root账户  s ...

  2. 【转】java中PriorityQueue优先级队列使用方法

    优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果不提供Comparator的话,优先 ...

  3. webpack4.x版本splitChunksPlugin的配置项详解与实际应用场景

    在工程化地使用webpack时,公共代码抽离是不可或缺的,4.x版本之后,commonsChunkPlugin已经被去掉,splitChunksPlugins登上舞台,并且优化了很多配置选项,集体课件 ...

  4. H5之画布canvas小记,以及通过画布实现原子无规则运动

    我们知道html在h5出之前就仅仅只是一个标签,一个标记,语义化并不强,后来新增的标签如video,audio都是语义化更强(让人一看就懂是什么东西,反正我是这么理解的,一个div不代表着什么),本身 ...

  5. .NET之EntityFramework框架运用

    1.创建EF模型库 创建类库-->添加新建项-->选择ADO.NET实体数据模型-->选择 来自数据库的EF选择器-->配置数据库链接以及相应的数据库-->看底部(将ap ...

  6. Struts标签库详解【3】

    struts2标签库详解 要在jsp中使用Struts2的标志,先要指明标志的引入.通过jsp的代码的顶部加入以下的代码: <%@taglib prefix="s" uri= ...

  7. mysql事务之间的隔离级别

    事务间未做隔离,会引起下面这些问题. 1.脏读:一个事务可读到另外一个尚未commit的事务中的数据. 2.不可重复读:在一个事务中,读取同一个数据 a,b,按顺序读取,在读a  b 之间,另外一个事 ...

  8. 附录C--拉格朗日对偶性

    1.原始问题 假设$f(x)$,$c_i(x)$,$h_j(x)$是定义在$R^n$上的连续可微函数,$x \in R^n$.考虑以下三类优化问题. 1.无约束的优化问题: \begin{align* ...

  9. CMD命令锦集

    虽然随着计算机产业的发展,Windows 操作系统的应用越来越广泛,DOS 面临着被淘汰的命运,但是因为它运行安全.稳定,有的用户还在使用,所以一般Windows 的各种版本都与其兼容,用户可以在Wi ...

  10. HTML5 CSS3 诱人的实例 : 网页加载进度条的实现,下载进度条等

    今天给大家带来一个比较炫的进度条,进度条在一耗时操作上给用户一个比较好的体验,不会让用户觉得在盲目等待,对于没有进度条的长时间等待,用户会任务死机了,毫不犹豫的关掉应用:一般用于下载任务,删除大量任务 ...