聊聊微服务链路服务

微服务架构

聊聊微服务链路服务

文章插图
图片
如果有用户反馈某个页面很慢 , 我们知道这个页面的请求调用链是 A ----->  C ----->  B ----->  D(图片有误) , 怎么来定位是由哪个服务引起的问题呢? 
更进一步,如果每个服务 Service A,B,C,D 都部署在好几台机器上 。怎么知道某个请求调用了服务的具体哪台机器呢?
聊聊微服务链路服务

文章插图
图片
可以明显看到 , 由于无法准确定位每个请求经过的确切路径,在微服务这种架构下有以下几个痛点:
1. 排查问题难度会比较大,解决问题的周期长
2. 特定场景很难再次复用
3.系统性能瓶颈分析同样也不同意
这就需要一个分布式调用链追踪系统 。
聊聊微服务链路服务

文章插图
图片
 
分布式调用链追踪系统:设计如果要我们自己实现一个这样的分布式追踪系统,该怎么去设计?
首先,我们必须得区分每个调用链,得给它分配一个全局唯一的 TraceID,并且在调用链上的每次调用都带上这个 ID,这样每个调用都被关联起来了 。
聊聊微服务链路服务

文章插图
图片
然后,我们得记录所有调用的先后次序和父子关系 。
假设有以上这样的调用链 , 如果我们只记录了这四个调用:
A---->B
B---->C
A---->D
D---->E
D---->F
虽然我们知道它属于一个调用(TraceID 相同) , 还是无法画出完整的调用拓扑图 。
所以必须得记录父子关系:
A---->B 是 B---->C 的父调用
A---->D 是 D---->E 的父调用
A---->D 还是 D---->F 的父调用
聊聊微服务链路服务

文章插图
图片
Agent微服务是来实现业务的,肯定不能来干这个监控和跟踪的活儿,那样对微服务的侵入性就太强了 。
所以必须得有一个独立的组件,在不干扰微服务的情况下,监控微服务之间的调用,把这些 ID 生成,这个独立的组件就是 Agent 。
Agent 要想施展魔法,需要安装在每个服务所在的机器上:
聊聊微服务链路服务

文章插图
图片
这个魔法师遵循的规则也非常简单,以上图中服务 A 上的 Agent 为例:
当 Agent 监测到有人调用服务 A 时,没有 ParentSpanID,它意识到这是一次全新的调用 , 于是创建新的 TraceID 。
当 Agent 察觉到 A 调用了 B 时,生成 SpanID = 1 , 并将此 ID 作为 ParentSpanID 传递给 B 。这样,当 B 调用 C 时 , B 的 Agent 就能生成此次调用的 SpanID 为 1.1 。
当 Agent 察觉到 A 调用 D 时,生成 SpanID = 2,并将此 ID 作为 ParentSpanID 传递给 D 。
4. 在 D 调用 E 和 F 时 , 分别生成 SpanID 2.1 和 2.2 。
指定微服务中的“RPC 调用的公用程序”(例如 Dubbo 中的 MonitorFilter.invoke方法),然后在运行时 , 通过动态修改字节码的方式来增强它:
聊聊微服务链路服务

文章插图
图片
当服务 A 调用服务 B 时,Agent 就可以做点儿手脚,修改 header 了:
 
聊聊微服务链路服务

文章插图
图片
数据收集Agent 虽然监控、生成了足够多的数据,但是单个 Agent 无法获得全局视图,我们需要一个全局的收集器来把 Agent 的数据收集上来 , 这样才能生成全局的调用链 。
结构如下图:
聊聊微服务链路服务

文章插图
图片

【聊聊微服务链路服务】


    推荐阅读