微服务,一般都是用复杂的、大规模分布式集群来实现的。微服务构建在不一样的软件模块上,这些软件模块,有多是由不一样的团队开发、可能使用不一样的编程语言来实现、有可能布在了几千台服务器,横跨多个不一样的数据中心。所以,就须要一些能够帮助理解系统行为、用于分析性能问题的工具。html
API网关Ocelot 做为微服务的一个重要组件,出如今系统边界上的一个面向API的、串行集中式的强管控服务,这里的边界是企业IT系统的边界,主要起到隔离外部访问与内部系统的做用。经过API网关对外发布的一般是OpenAPI,在它的后面有众多的分布式应用,如微服务、消息收发、分布式数据库、分布式缓存、分布式对象存储、跨域调用,这些组件共同构成了繁杂的分布式网络。前端
当应用A发出某个请求时,其背后可能有数十个甚至更多的服务被调用,可谓是“牵一发而动全身”。 若是将分布式系统比做高速公路网,每一个前端的请求就至关于高速上行驶的车辆,而处理请求的应用就是高速上的收费站,在收费站上将车辆通行信息记录成日志,包括时间、车牌、站点、公路、价格等,若是将全部收费站上的日志整合在一块儿,即可以经过惟一的车牌号肯定该车的完整通行记录;分布式调用系统跟踪和监控就是类比这种思想,对每一次请求进行跟踪,进而明确每一个请求所通过的应用、耗时等信息。git
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 来实现这个功能,让咱们的微服务可以可运维。github
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点:后端
1、将追踪数据串起来,让咱们能够在Butterfly UI上直观的看到各个节点的数据api
2、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这块功能也是须要继续开发的功能,欢迎各位同窗一块儿加入开发。
还有链路分析,链路与调用链不一样,链路是一个统计学的概念,而调用链是单体调用的过程。分析链路的拓扑形态分析:分析来源、去向,识别不合理来源;
上图是全局调用拓扑图,能够明显的看到不一样的服务之间存在复杂的调用关系,也能够查看某个服务和其余服务之间的调用关系以及调用的频次; 经过该拓扑图,架构师能够清楚地观察到系统上的调用状况。