关于架构:链路追踪技术的应用及实践

3次阅读

共计 3335 个字符,预计需要花费 9 分钟才能阅读完成。

文 | 丹青

网易智慧企业资深架构师

链路追踪背景

如图所示,在微服务体系中,一个申请往往须要多个服务合作解决。

凡事无利必有弊,这种模式在给咱们带来更好的可扩展性的同时,也带来了一些新的问题。例如,排查问题的艰难:任意节点的异样都可能导致上游链路的异样,难以追根溯源;零碎拓扑简单难以把控,健壮性存在隐患。

2010 年,谷歌发表了一篇论文,介绍了谷歌的外部链路追踪零碎 Dapper 的设计,链路追踪技术自此进入社区的视线。

上面,咱们将简略介绍其在 APM 畛域的利用,以及在服务依赖治理和研发效力晋升方面的实际。

APM

分布式系统中,一个申请会在多个节点之间流转,APM 通过 TraceID 将整条申请解决链路中的相干节点关联起来,并记录每个节点的执行工夫等信息,造成申请的生命周期链路。

如图,咱们能够很直观地看到申请通过了哪些节点,以及各个节点的解决耗时。这使得咱们在关注服务自身运行状态的同时,还能从申请生命周期的视角关注到整条申请链路上的所有细节及指标,大幅提高了咱们排查定位问题的效率。

服务依赖治理

不合理的依赖,可能导致边缘系统的故障拖垮外围服务,威逼到分布式系统整体的稳定性。通过链路追踪数据的汇总剖析,咱们能够绘制出零碎间的依赖拓扑,为依赖治理提供数据撑持。

咱们个别会从上面三个角度来评估服务依赖的合理性:

  • 反向依赖。反向依赖指高等级服务依赖了低等级服务。例如,租户服务是咱们的外围服务之一,而统计服务重要性绝对较低,显然,咱们不容许租户服务依赖统计服务。通过服务拓扑图和服务等级的联合,咱们能够很容易的将反向依赖剖析自动化,实时预警。
  • 强弱依赖。强依赖指上游服务产生异样时,将影响以后节点的稳定性。在设计时,咱们应该充分考虑强依赖在以后场景中的必要性。强依赖是否能够弱化,如果不能,业务场景是否容许加上熔断降级之类的的保护措施。强弱依赖的梳理,咱们能够联合故障注入工具,产出系统化的报告。
  • 环状依赖。环状依赖往往是边界不清晰的体现,绞成一团,档次不清。对环状依赖的梳理也是咱们对业务边界和零碎边界的梳理,对系统整体健康度的晋升十分有意义。

研发效力晋升

随着业务的倒退,研发团队的规模在肯定阶段也会相应地一直晋升,但撑持咱们研发流动的基础设施却没有方法线性增长,这其中最重要的就是联调或测试环境。

业务倒退往往导致并行迭代的增多,而这些并行迭代难免会改变到雷同的服务,尤其是一些外围根底服务。如下图,

这就会导致两个问题——

1. 环境抢夺。如图,Story- B 须要部署 ticket 服务,与此同时 Hotfix- A 也期待验证,同样须要部署 ticket 服务,这意味着至多有一方会被阻塞期待,这种串行模式,极大地升高了咱们的交付效率。并行迭代越多,效率升高越显著。

2. 环境的稳定性。服务之间是互相分割的,任何服务的不稳固都可能会导致该环境的不稳固。上图中的 auth 服务,简直要被所有的业务流程应用。如果 Story- A 部署 auth 服务时,重启 / 部署的过程不够平滑,或者 Story- A 的代码中存在某些 bug,那么会造成整个测试环境的不稳固。

我的项目规模不大时,咱们往往能通过一些管理手段来协调。例如版本串行化,通过将迭代打算错开,防止在同一个时间段都要去部署某个服务。测试环境只部署特定分支,须要验证时则将各自的代码都合并到此分支;要求部署到测试环境的代码必须达到某种规范以晋升测试环境的稳定性。

然而咱们也能够看到,管理手段的有效性是和团队规模微服务规模反相干的,咱们须要有技术手段来达到更好的成果。

细想一下,其实问题的本源是大家共用一套测试环境,所以咱们的研发流动呈现了资源竞争,咱们对某个服务的操作可能影响到其余服务。

那么,是否让大家都能轻松创立各自的环境,且各个环境的应用互不影响呢?

如上图,Story- A 须要部署 user 和 auth 服务,那么咱们创立 env- 1 并部署咱们的 user 和 auth; Story- B 须要部署 ticket 服务,那么咱们就创立 env- 2 并部署 ticket 服务;env- 3 同理。

为了形容不便,咱们把上图中的 env- x 环境,叫测试环境;图中的下半局部,叫回归环境。测试环境只蕴含本次迭代须要部署的利用,回归环境蕴含所有利用。

当咱们应用这套机制时,咱们冀望 env- 1 的使用者,申请 user 和 auth 服务时只会路由到 env- 1 环境,申请其余服务时路由到回归环境。env- 2 环境的使用者,申请 ticket 服务时只会路由到 env- 2 环境,申请其余服务时同样路由到回归环境。

也就是说,对于环境使用者的申请,如果相干的利用在该环境内,则申请只会被该环境内的利用解决,否则路由到回归环境解决。

回归环境是一个蕴含所有服务的绝对稳固的环境,开发和提测不容许在回归环境部署,以此来保障足够的稳定性。

研发流程方面,咱们不再像以前一样部署到大家都在应用的环境中去验证,而是各自创立各自独享的环境,在本人的环境中实现相干工作。

咱们将上述机制称之为 环境隔离,要实现环境隔离,技术侧至多须要实现两方面的能力:

  • 辨认并传递申请对应的环境信息
  • ⼲预中间件的实例抉择 / 生产规定

辨认并传递申请对应的环境信息

首先,咱们须要能将申请和测试环境关联起来。

辨认申请对应的环境信息,这意味着咱们在创立测试环境时须要指明某种标识,且这种标识咱们能够从申请中提取出,从而通过单方标识的匹配来实现关联,这种标识能够是用户账号、某组 IP,或者企业租户,应用哪种形式不重要,重要的是联合业务特点达到不便易用的目标。

例如,在咱们的 SaaS 零碎七鱼里,咱们应用租户 id 来作为咱们的标识。在咱们的平台创立测试环境时,除了指明要部署的利用外,咱们还须要输出租户信息,通过这种形式实现申请和测试环境的映射。

咱们能够在申请的对立入口处(例如,网关),获取到申请所属的租户,之后咱们能够进一步拿到它所属的环境信息(环境 ID、利用列表)。相似于链路跟踪零碎在申请链中传输 TraceID,咱们在申请链中附加上环境信息,为环境隔离打下基础。

⼲预中间件的实例抉择 / 生产规定

咱们以微服务架构中最罕用的几个组件为例,谈谈环境隔离的实现形式。

RPC 框架——

RPC 的外围流程:provider 实例将本人注册到注册核心,consumer 通过注册核心获取 provider 实例列表,依据肯定的实例筛选策略和负载平衡算法,抉择其中一个实例发动调用。

所以革新的伎俩很明确,provider 启动时,咱们在元数据中写入环境 ID。在实例抉择时,咱们从申请的链路数据中拿出环境 ID 与之做匹配。

须要特地留神的是,匹配不到符合要求的实例时,咱们不能简略的认为 no provider 而让程序报错,咱们须要思考该 provider 所属的利用是否在对应环境利用列表中,如果不在,咱们须要将申请路由到回归环境中。

消息中间件——

RPC 在调用之前有如上所述的实例筛选过程,但消息中间件没有这个逻辑,不过咱们仍然能够干涉生产规定,即在消费者拿到音讯后判断是抛弃音讯还是生产该音讯。以 kafka 为例,测试环境的 kafka consumer 启动时,批改 consumer groupid 为 groupid_${env}。kafka consumer 接管到音讯时,执行和上述 RPC 框架筛选实例时相似的逻辑即可。

定时工作——

定时工作其实最为非凡。前文中咱们提到,在申请的对立入口,查问申请所对应的环境信息并写入链路。然而定时工作发动的申请并不是用户触发的,它来自零碎外部,定时调度组件才是申请的“源头”。所以咱们须要在定时工作执行之初,就退出咱们的判断标识逻辑,这要求咱们:

  • 定时工作须要有对立的调度平台,防止各业务模块姿态各异,无奈由通用组件对立解决
  • 针对调度组件的工作散发 / 分片机制的革新,对立形象执行层,退出环境隔离逻辑

结束语

在网易智慧企业中,链路追踪技术的利用,晋升了咱们的问题排查效率以及对申请链路的把控,也为服务依赖治理提供了必要的数据撑持。同时环境隔离也极大地晋升了交付效率和测试环境的稳定性,从而进步了研发团队的整体幸福感。

整体来说,咱们构建了对立的链路追踪体系,撑持了服务依赖治理及环境隔离技术的实现,但这并不是起点,咱们还能够挖掘更多的场景,比方 SaaS 零碎的多租户资源隔离,或者异样监控预警。世界很大,一起多摸索。

正文完
 0