类似Google Dapper,为微服务打造分布式跟踪工具

概述

作为工程师,我们总是喜欢让事情变得简单化、自动化。其实仔细去想,面向过程编程就是这种思维的产物之一,再到后来,我们发明了面向对象编程。不管是哪种编程模式,这些概念永远都有着核心的共同点:把一些大的东西折分成小的、独立的模块,再开放或者共用抽象层,隐藏实现层的细节。

抽象化

抽象能够帮助我们更好的理解大型的、复杂的系统,同时编写独立的模块也更有效率。我们进行系统架构设计的方式也在不断地革新:

  • 客户端-服务端 N层架构

  • SOA 面向服务编程

  • 微服务架构

分而治之

如果你去分享,不难发现,这些实现方式都包含的相同的架构思想和理念,这也是为什么聊聊架构一直在推崇先去理解架构的道,再去看架构图的原因之一。

  • 把系统解耦成更小的单元

  • **单一职责原则(SRP):**每个单元都有自己的职责 —— 做好一件事情

  • **开放封闭原则(OCP):**每个单元通过API暴露,外界不需要关心它的具体实现

  • ** 应用隔离原则(ASP):**所有的单元都是独立的,可以独立的进行开发、部署、扩展、以及监控

  • **依赖反转原则(DIP):**各个单元之间可以通过RPC请求进行交互

我们可以通过不断的添加新的、小的模块或者重用已经有的模块来构建复杂的系统。我们通过构建模块,然后通过这些模块来构建任何我们想要的东西。就像“乐高”一样,在合适的地方添加你想要的东西。

当然我们必须要保持平衡,对于微服务架构而言也没有例外。系统的耦合度越低,我们能控制的就越少。最后我们可能就只知道我们有一个很酷的基础架构下面有很多的微服务互相交互,有时候可能都看不到一个整体的、全局的视野。

微服务的世界

输入图片说明

这是一个典型的微服务架构,我们可以看到6个微服务和一些依赖项(可能一些RPC的调用)。同时,在一段时间的尝试和研究之后,我们发现了一些可用的基础架构型模式:微服务路由(micro-service routes)。

输入图片说明

所以我们看到了3个微服务路由:

  • 新用户注册——由微服务A,B,C,和E实现

  • 下订单——由微服务A,B,C,和D实现

  • 支付——由微服务A,B,C,D和F实现

如你所见:

  • 有一些服务相对来说更重要、常用 (A,B,C和D)

  • 有一些服务几乎不怎么被使用(E和F)

  • 常用的服务对于某些服务路由来说可能会造成瓶颈(C和D)

想象一下这样的一个场景:某一天突然你的“支付流程”变慢了,事出必有因。你需要收集那些比平台慢3倍的支付请求记录,来找到是什么地方、原因导致的。同时,如果是由于某些特殊的场景导致的,怎么办?

比如说,只有澳大利亚的部分客户,他们的收件箱里面有未读消息,导致他们在支付的时候只有30%的情况下是成功的。你在丢失利润的同时,也有可能丢失忠诚的用户。你知道“支付”路由包含了A,B,C,D和F微服务,但是却完全不知道到底发生了什么?这种事情时有发生,如恶梦般,对吗?

在一些常见的软件里面,我们有一些工作可以帮助我们很容易的找到问题,比如debugger和profiler。 这是单体应用程序的好处,一切都是运行在同一个进程里面。但是一旦我们的程序使用了RPC请求之类的玩意儿,我们在这些超级酷的工具APM/debugger/profler等工具下面将只会看到这样的信息:“外部请求XYZ超时16.5秒…” 这还真的是挺慢的,但是我们仅仅发现了一个瓶颈。

不要太快

这会帮助你发现你的App正在经历的一些延迟问题吗?答案是“Yes”。这会帮助你修复问题让你的App恢复快速的网络访问吗?答案是“No”。如果那个XYZ服务又调用了其它三个服务怎么办?如果后面三个服务同样的也有其它服务的请求呢?如果你有20+个微服务在用不同的方式互相调用,怎么办?

这就是现如今,当我们把业务解耦成小的、独立的、分布式的、通过网络访问的单元(也就是微服务)之后的世界。欢迎来到这个你看不到任何东西的世界!

所以我们需要从全局、整体层面去看我们的系统:

  • 去理解哪些微服务down掉了

  • 哪些路由被这些down掉的服务影响

  • 什么原因导致它不能工作了

  • down掉的频率是多少

分布式跟踪管理

我们对于某一个具体的微服务了解的很全面,但是我们还想知道他们在不同的场景下是如何作为一个组合与其它微服务来交互的。所以我们需要另一个视角。

你可记得Chrome开发者工具或者Firebug下的 “网络(Network)” 选项卡?当你想知道为什么一些页面加载缓慢的时候,你就可以打开开发者工具的“网络”选项卡查看时间线图表。然后就可以看到是哪些资源阻塞了页面的加载和渲染过程。

输入图片说明

现在你可以想象一下如果你有同样的工具查看后端的一些东西呢?比如说微服务?那些请求树就是我们的微服务路由,我们同样可以看到时间线!微服务之间在发起RPC请求等待回应的时候互相等待。

所以对于下面这张图:

输入图片说明

你会看到这个样子:

输入图片说明

现在我们可以看到:

  1. A调用B然后等待

  2. 在A拿到B的结果之后,然后调用了C

  3. C花了相对较少的时间,然后调用了D

  4. D花费了一些时间之后调用了F

  5. F在非常短的时间内处理完毕并将结果返回给了D

  6. D拿到F返回的结果之后,花了不少的时间处理

  7. D回复给C

  8. C拿到D的结果之后没有做什么处理,直接返回给了A

  9. A拿到C返回的结果

  10. 我们的“支付”微服务路由完成,并将结果返回给了客户端

哈哈,这已是有了很多我们想要的东西。我们不知道为什么它会是这个样子的。所以,你已经看到了在哪里花费了最多的时间?是的,就是微服务D!A在等C,C在等D,而D几乎花了一半的时间。所以现在我们知道了“支付”这个路由的瓶颈在服务D。

下面的问题是:还有哪些微服务路由中也同时包含了对服务D的请求?是否也有瓶颈?不管怎么说,我们现在知道了D在我们的“支付”这个微服务路由中是有瓶颈的,那我们就先修复这个问题。

下面有一些关键点:

  • 我们可以从一个时间线的视角来查看一个微服务路由。

  • 我们可以以一种树形的方式看到一个调用请求栈。

  • 这个树在一个微服务路由的生命周期内随着时间的推进从左向右的生长。

  • 我们可以看到一些微服务的请求,它们的交互过程。

最关键的是:我们可以看到哪里花了最多的时间,总是有一个最坏的 人要让所有其他人等它(记得午餐的时候吗?当你非常想去一个可以 吃到某一个东西的时候,你很想立马就去,但是你不能,因为你必须要等某个人)。

我们也可以在这个时间线上看到网络延时,我们将知道是一个微服务的问题还是网络的问题。

这个时间线将能给你一些关于如何优化、加速你的微服务的建议。比如说:把A到B和A到C做成并行请求如何?我们真的需要等到B返回结果之后才能去请求C吗?

你可能会问怎么样可以做到这样?这就是分布式跟踪系统将要给你的,像Google Dapper这样的。关于分布式跟踪系统的实现是另外一个更大的话题,我会在后续的博客中继续更新,请保持关注。感兴趣的同学可以点击阅读原文查看Google Dapper的相关资料。

转载于:https://my.oschina.net/jimilee/blog/733163

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值