Ocelot 集成Butterfly 实现分布式跟踪

微服务,通常都是用复杂的、大规模分布式集群来实现的。微服务构建在不同的软件模块上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。因此,就需要一些可以帮助理解系统行为、用于分析性能问题的工具。

API网关Ocelot 作为微服务的一个重要组件,出现在系统边界上的一个面向API的、串行集中式的强管控服务,这里的边界是企业IT系统的边界,主要起到隔离外部访问与内部系统的作用。通过API网关对外发布的通常是OpenAPI,在它的后面有众多的分布式应用,如微服务、消息收发、分布式数据库、分布式缓存、分布式对象存储、跨域调用,这些组件共同构成了繁杂的分布式网络。

当应用A发出某个请求时,其背后可能有数十个甚至更多的服务被调用,可谓是“牵一发而动全身”。 如果将分布式系统比作高速公路网,每个前端的请求就相当于高速上行驶的车辆,而处理请求的应用就是高速上的收费站,在收费站上将车辆通行信息记录成日志,包括时间、车牌、站点、公路、价格等,如果将所有收费站上的日志整合在一起,便可以通过唯一的车牌号确定该车的完整通行记录;分布式调用系统跟踪和监控就是类比这种思想,对每一次请求进行跟踪,进而明确每个请求所经过的应用、耗时等信息。

Butterfly被设计为分布式追踪和APM的Server端,它将包含Collector,Storage,独立的Web UI,并使用Open Tracing规范来设计追踪数据。目前仅根据规范实现了Open Tracing API,后续还会兼容google的opencensus。这里顺便提下为什么我们不用zipkin 或是Jaeger,他们只做了tracing,Butterfly比他们多一点就是同时要做metrics和预警,就是要做立体化监控系统。目前Butterfly也是在起步阶段,还有非常多的功能需要开发,目前有两个事情的优先级比较高一个应用程序进程级别的metrics,一个是后端collector和es的性能优化,欢迎各位同学加入一起开发,我们相信通过不断的建设,我们.NET社区一样可以达到Java的高度。回想Ocelot 的发展历程,2016年才是到现在已经开发了2年时间,完成了3.0版本的开发,现在已经是一个日趋成熟的API网关,通过API网关连接后面的服务,像今天和大家分享的最近我业余时间在开发的分布式跟踪的支持,这项任务在一年前提出来,https://github.com/TomPallister/Ocelot/issues/19 这里有我们的讨论,现在集成Butterfly 来实现这个功能,让我们的微服务能够可运维。

Butterfly.Client.AspNetCore 为我们提供了在ASP.NET Core项目集成Butterfly的组件,使用很简单,只需要在ConfigureServices 注册Butterfly services

public void ConfigureServices(IServiceCollection services) {   //your other code services.AddButterfly(option =>{option.CollectorUrl = "http://localhost:9618";option.Service = "my service";});
}

其中http://localhost:9618 是Butterfly的服务端,提供了UI,我们在浏览器通过http://localhost:9618 就可以访问到。

那么在API网关Ocelot 中集成Butterfly 有什么不一样呢? 我们在Ocelot项目中加入上述代码后,我们已经可以在Butterfly UI上看到我们的追踪数据,只是数据没有连成一条链。那么我们做集成的工作主要就是以下2点:

一、将追踪数据串起来,让我们可以在Butterfly UI上直观的看到各个节点的数据

二、Ocelot 本身需要加入到系统跟踪的数据定义

Ocelot 集成Butterfly 实现分布式跟踪的代码目前还没有加入主干,可以在我的代码库的分支https://github.com/geffzhang/Ocelot/tree/Monitoring下看到,我们首先在Ocelot的路由配置中加入一个配置项,表示是否启用分布式追踪:

{
   "ReRoutes": [
     {
       "DownstreamPathTemplate": "/api/values",
       "DownstreamScheme": "http",
       "UpstreamPathTemplate": "/api/values",
       "UpstreamHttpMethod": [ "Get" ],
       "DownstreamHostAndPorts": [
         {
           "Host": "localhost",
           "Port": 5002
         }
       ],
       "HttpHandlerOptions": {
         "AllowAutoRedirect": true,
         "UseCookieContainer": true,
         "UseTracing": true
       }
     },

UseTracing 表示是否启用分布式追踪,默认为false,也就是不启用。 然后在Ocelot.DependencyInjection.IOcelotBuilder 加个接口方法:

方法的实现也非常简单:

主要就是加入Ocelot 本身需要加入到系统跟踪的数据定义,实现上主要使用DiagnosticSource, 官方的文档:https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/DiagnosticSourceUsersGuide.md 。类似于asp.net core 有个 Diagnostics中间件https://github.com/aspnet/Diagnostics,主要功能是用于报告和处理ASP.NET Core中的异常和错误信息,以及诊断Entity Framework核心迁移错误。其中还有其他几项功能,欢迎页,错误代码页、如404 页等。以及一个还算不错的日志查看功能,这个功能也是很多人需要的功能,直接在线查看日志。

实现了Butterfly 的接口ITracingDiagnosticListener ,通过DI 注入后Butterfly 会帮我们注册好。

下面我们要把我们的分布式追踪数据串起来,OpenTracing(链接:opentracing.io)通过提供平台无关、厂商无关的API,使得开发人员能够方便的添加(或更换)追踪系统的实现。OpenTracing正在为全球的分布式追踪,提供统一的概念和数据标准。标准的中文版是我们的MVP吴晟翻译的,同时他也是OpenTracing的主要成员 : https://wu-sheng.gitbooks.io/opentracing-io/content/。

在广义上,一个trace代表了一个事务或者流程在(分布式)系统中的执行过程。在OpenTracing标准中,trace是多个span组成的一个有向无环图(DAG),每一个span代表trace中被命名并计时的连续性的执行片段。

分布式追踪中的每个组件都包含自己的一个或者多个span。例如,在一个常规的RPC调用过程中,OpenTracing推荐在RPC的客户端和服务端,至少各有一个span,用于记录RPC调用的客户端和服务端信息。

一个父级的span会显示的并行或者串行启动多个子span。在OpenTracing标准中,甚至允许一个子span有个多父span(例如:并行写入的缓存,可能通过一次刷新操作写入动作)。

所以集成的关键点就在tracerId和spanId的关联关系的Id 处理上。

tracerid 代表是全局的id,类似于Ocelot的RequestId http://ocelot.readthedocs.io/en/latest/features/requestid.html,存放在http header 里,它的key是ot-traceid,所以在Ocelot里面可以把全局的RequestId设置为ot-traceid 。

同时还需要处理spanid,使得下游的的组件的spanid是它上一级的spanid,也是存放在http header 里,它的key是ot-spanId,我们在OcelotRequestTracer 以及OcelotHttpTracingHandler 需要处理spanid

上面我们说完了代码集成工作,我们来看看效果吧,我搭了一个Demo环境,服务前端—>Ocelot –>服务后端。Butterfly为每个请求生成全局唯一的ID(Traceld),通过它将不同系统的“孤立的”调用信息关联在一起,还原出更多有价值的数据。

上图是一条API调用请求的调用链,在Span列可以看到请求中间过程所经过的一系列应用组件,可以看到最先经过请求端的HttpClient组件,后续调用Ocelot、HttpClient、backend等,形成调用树(树上的缩进表示嵌套关系),从调用树上很容易看到前端请求的完整处理过程。在上图所示的页面中也清晰地展示了每块应用处理请求得具体耗时,非常直观地进行定位;此外,点击具体的组件,可以看到这个组件中的日志记录

对于分布式调用跟踪系统而言,它并不仅仅提供了调用链这一功能,因为它对所有中间件的调用做埋点,所以中间件上的所有情况都可以监控的到。因此,在形成调用链的过程中也会形成一份详细的调用监控报表,它与其他监控的不同之处在于:该监控报表是带有上下钻取功能的报表。因为调用链是详细的底层统计,对上可以形成的报表维度是非常丰富的,在上图所示的调用报表里,不仅可以看到服务的情况,还可以下钻到它所调用服务的情况;另外从监控报表上还可以进行调用链的下钻,查看清晰的调用链信息。目前Butterfly这块功能也是需要继续开发的功能,欢迎各位同学一起加入开发。

还有链路分析,链路与调用链不同,链路是一个统计学的概念,而调用链是单体调用的过程。分析链路的拓扑形态分析:分析来源、去向,识别不合理来源;

上图是全局调用拓扑图,可以明显的看到不同的服务之间存在复杂的调用关系,也可以查看某个服务和其他服务之间的调用关系以及调用的频次; 通过该拓扑图,架构师可以清楚地观察到系统上的调用情况。

相关文章:

  • Ocelot——初识基于.Net Core的API网关

  • Ocelot API网关的实现剖析

  • 微服务网关Ocelot

  • API网关Ocelot 使用Polly 处理部分失败问题

  • 谈谈微服务中的 API 网关(API Gateway)

  • Ocelot网关

  • Ocelot统一权限验证

  • 应用监控怎么做?

  • ASP.NET Core之跨平台的实时性能监控

  • .Net Core 2.0+ InfluxDB+Grafana+App Metrics 实现跨平台的实时性能监控

  • 应用程序的8个关键性能指标以及测量方法

  • 使用Metrics监控应用程序的性能

  • 下一个计划 : .NET/.NET Core应用性能管理

  • Ocelot监控

原文:http://www.csharpkit.com/2018-02-04_51207.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322187.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

聊聊AspectCore动态代理中的拦截器(一)

前言在上一篇文章使用AspectCore动态代理中,简单说明了AspectCore.DynamicProxy的使用方式,由于介绍的比较浅显,也有不少同学留言询问拦截器的配置,那么在这篇文章中,我们来详细看一下AspectCore中的拦截器使用。两种配…

你可能不知道的.Net Core Configuration

执行原理1. 配置读取顺序:与代码先后顺序一致。public Startup(IHostingEnvironment env){var builder new ConfigurationBuilder().SetBasePath(env.ContentRootPath).AddJsonFile("appsettings.json", false, true).AddJsonFile("cussettings.jso…

Dubbo(一)之简介

转载自 Dubbo 2.7入门 一、背景 本文介绍了网站应用的演进 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。 单一…

Dubbo(二)之SpringBoot nacos集成

一、框架 使用springboot启动&#xff0c;注册中心现在naocs。 nacos安装 二、样例项目 &#xff08;1&#xff09;maven设置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId> <…

ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线

在上文中&#xff0c;我们讨论了事件处理器中对象生命周期的问题&#xff0c;在进入新的讨论之前&#xff0c;首先让我们总结一下&#xff0c;我们已经实现了哪些内容。下面的类图描述了我们已经实现的组件及其之间的关系&#xff0c;貌似系统已经变得越来越复杂了。其中绿色的…

浅谈开发模式及架构发展

一、传统开发模式传统的开发模式基本一般是重服务端的开发方式&#xff0c;大部分工作都在服务端执行&#xff0c;然后返回到客户端&#xff08;通常是HTML&#xff09;。以Asp.net MVC为例&#xff0c;如下图&#xff1a;#1 根据请求的路由定位到对应的Controller的对应的Acti…

Dubbo(四)之xml配置方式

转载自 Dubbo xml配置方式 以 XML 配置的方式来配置你的 Dubbo 应用 有关 XML 的详细配置项&#xff0c;请参见&#xff1a;配置参考手册。如果不想使用 Spring 配置&#xff0c;而希望通过 API 的方式进行调用&#xff0c;请参见&#xff1a;API配置。想知道如何使用配置&a…

Actor-ES框架:Ray-Handler之CoreHandler编写

如图右上角所示&#xff0c;Ray中有两类Handler&#xff08;SubHandler和PartSubHandler&#xff09;,在使用中&#xff0c;SubHandler派生Actor的CoreHandler&#xff0c;PartSubHandler派生SQLToReadHandler&#xff0c;SQLToReadHandler派生Actor的ToReadHandler&#xff0c…

Dubbo(五)之动态配置中心

转载自 Dubbo动态配置中心 Dubbo 2.7 中的动态配置中心 配置中心&#xff08;v2.7.0&#xff09;在 Dubbo 中承担两个职责&#xff1a; 外部化配置。启动配置的集中式存储 &#xff08;简单理解为 dubbo.properties 的外部化存储&#xff09;。服务治理。服务治理规则的存储…

使用Mono将C#编译运行至WebAssembly平台

因为所有的主流网页浏览器都支持WebAssembly&#xff0c;开发者们现在可以寻找一个新的平台来部署他们的应用程序。由WebAssembly团队提供的标准工具链仅能将C、C编译成为WebAssembly&#xff0c;然而这对使用其他编程语言的开发者们并没有什么帮助。C#开发者就幸运的多了&…

Dubbo(六)之属性配置

转载自 Dubbo属性配置 属性配置 以属性配置的方式来配置你的 Dubbo 应用 如果你的应用足够简单&#xff0c;例如&#xff0c;不需要多注册中心或多协议&#xff0c;并且需要在spring容器中共享配置&#xff0c;那么&#xff0c;我们可以直接使用 dubbo.properties 作为默认…

使用Docker分分钟启动常用应用

前言Docker是目前比较火的一个概念&#xff0c;同时也是微服务中比较关键的一个容器化技术。但是&#xff0c;单从理论上好难看出Docker的优势&#xff0c;因此&#xff0c;我希望在这篇文章中提供一些Docker的使用示例&#xff0c;希望从实际应用上帮助大家理解Docker的优势&a…

nssl1337-矩形统计【单调栈】

正题 题目大意 一个n∗nn*nn∗n的矩阵&#xff0c;然后有些位置破损。求可以剪出多少个不破损的矩形。 解题思路 预处理upi,jup_{i,j}upi,j​表示从(i,j)(i,j)(i,j)向上多少格子都是非破损格子。 然后我们枚举下界LowLowLow&#xff0c;将图像变成一个下部平整的条形图&…

TypeScript 2.7 版本发布

TypeScript 2.7版本已经发布了&#xff0c;新增了几个主要功能特性并进行了一些bug的修正。其中一些亮点包括对类属性的赋值检查、固定长度的元组和改进对象文字的类型推断。总的来说&#xff0c;这个版本对类型系统、ES2015特性和总体的TypeScript开发者体验都进行了改进优化。…

Azure Functions + Azure Batch实现MP3音频转码方案

客户需求客户的环境是一个网络音乐播放系统&#xff0c;根据网络情况提供给手机用户收听各种码率的MP3歌曲&#xff0c;在客户没购买歌曲的情况下提供一个三十秒内的试听版本。这样一个系统非常明确地一个需求就是会定期需要将一批从音乐版商手中获取到的高比特率音乐文件转换成…

Springboot Mybatis多数据源配置MybatisProperties坑

一、场景复现 配置了两个数据源&#xff0c;查询Dao却报错表不存在。 &#xff08;1&#xff09;maven <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId> </dependency> …

dotnet core webapi +vue 搭建前后端完全分离web架构(一)

架构服务端采用 dotnet core webapi前端采用: Vue router elementUIaxios问题使用前后端完全分离的架构&#xff0c;首先遇到的问题肯定是跨域访问。前后端可能不在同个server上&#xff0c;即使前后端处在同个server上&#xff0c;由于前后端完全分离&#xff0c;前后端使用…

SpringBoot使用日志

转载自 SpringBoot使用日志 1、选什么日志框架 首先列举一下日志门面和实现SpringBoot默认选用SLF4J和Logback日志级别&#xff1a;springboot默认已经帮我们配置好了日志&#xff0c;日志级别为trace<debug<info<warn<error默认的日志级别为inifo&#xff0c;日…

Dotnet Core Windows Service

在dotnet 中有topshelf 可以很方便的写windows 服务并且安装也是很方便的&#xff0c;命令行 运行.exe install 就直接把exe 程序安装成windows 服务。当然代码也要做相应的修改&#xff0c;具体的可以参照例子。在dotnet core 2.0 中 我们也有一个很方便的dll 来使用 https://…

Dubbo(十)之配置加载流程

转载自 Dubbo配置加载流程 Dubbo 中的配置加载流程介绍 此篇文档主要讲在应用启动阶段&#xff0c;Dubbo框架如何将所需要的配置采集起来&#xff08;包括应用配置、注册中心配置、服务配置等&#xff09;&#xff0c;以完成服务的暴露和引用流程。 根据驱动方式的不同&…