14

达达京东到家:微服务架构下的链路管理

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzAwMzg1ODMwNw%3D%3D&%3Bmid=2653792140&%3Bidx=1&%3Bsn=d0297142cc4b47781c070172ce84decb
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

作者简介

顾宝碗:达达京东到家架构师,在系统高可用,服务治理,基础中间件等方面有丰富的行业经验。

万明明:达达京东到家新晋架构师,明明可以靠颜值吃饭,偏偏却要写代码。

背景

随着达达的业务发展,我们在微服务的推进过程中也遇到了很多业内相同的痛点,比如:

  • 很难在生产环境下进行全链路的压力测试,每次压测耗时耗力且经济不划算

  • 同一服务的不同版本很难在测试环境同时测试

  • 某些新功能上线需要同时更新多个服务,但是灰度流量没办法只在更新的服务中处理,给我们灰度验证增加了麻烦

具体来说:

全链路压测

达达之前的压力测试需要完整的搭一套新的环境,但是整个过程耗时耗力,成本非常高昂。我们希望可以直接在线上的机器中隔离出来一部分流量专门用来压力测试,以省去我们重新搭环境的成本。

并行功能测试

产品迭代速度较快,有时候需要我们在同一时间测试同一服务的不同版本,导致测试资源大量阻塞在竞争测试环境上。在这种场景下,如何避免不同的测试间的相互干扰便成了一个急需被解决的问题。

线上灰度发布

为了降低新版本上线可能产生的风险,我们需要隔离部分线上流量用来做灰度验证,这也是我们急需要解决的问题。

所以,基于以上的各种问题,我们需要开发一套系统以便我们可以灵活的管控流量。

解决方案 实现

为了解决以上的问题,我们抽象了一种叫做“ 链路 ”的逻辑概念,即一个业务请 求从进入系统到完成处理所经过的所有微服务以及数据节点组成的路径。

如下图所示:

RruAzeF.png!web

在上 面的示例图中,一个请求可以被分发到两个不同的链路(“链路A”与“链路B”)中。 在默认情况下,如果一个链路中包含完整的上下游服务,则进入该链路的流量只会在该链路内流转。 可是,在真实场景中不是所有的链路都会包含完整的微服务拓扑,此时,就需要我们根据链路的不同特点和需求,来决定流量(在本链路中找不到下游服务节点的情况下)是否需要被转向至其他链路中。 因此,我们将“链路”又拆分为两种不同类型: 强链路 ”(不允许流量转向到其他链路)与“ 弱链路 ”(可以将流量转向至其他链路),我们会在最后一个章节中详细阐述这两种链路的真实应用场景。

基于以上的定义,为了解决在第一章提出的各个问题,我们使用consul作为我们底层服务注册和发现的引擎,且我们为了治理这些节点和链路之间的流量开发了一套管理和监控的工具。

达达的整个服务治理逻辑架构图如下所示:

ZRv2qyR.jpg!web

我们将所有无状态的业务 服务归类为应用集群,同时我们将所有有状态的数据节点(数据库,缓存,消息队列等)归类为数据集群。 他们之间的调用关系只存在于:

  • 应用集群节点之间的相互调用

  • 应用集群节点调用数据集群节点

且无论何种调用,我们都希望调用方只知道被调用方的名称即可,而无需理会其他的各类细节(如被调用方的可用性,节点地址,访问权限等),以尽量降低调用的开发成本,提升效率。这就要求我们可以将所有调用细节进行抽象和统一管理。

除了以上大家都熟悉的服务注册和发现治理之外,因为我们需要通过“链路”来进行更细粒度的流量管控,所以我们需要一套灵活稳定的底层引擎来支持整套技术系统的完美运行。

基于consul的tag功能,我们通过给不同节点设置不同的tag来实现“链路”功能,举例来说,压测“链路”中的节点都被打上了“压测”的tag。

有了以上基础设施和功能的铺垫之后,我们自研了一套中间件系统来实现我们所希望支持的所有调用逻辑。且我们还开发了一套管理控制台(我们称为Director)来方便我们治理系统内部的所有节点和“链路”。

真实业务场景应用

基于以上的解决方案,我们根据达达的实际业务场景和需求,将线上环境划分为以下几条链路:

a2yAnuq.png!web

基础链路

我们将用于处理日常线上业务的节点都归于基础链路之中。

灰度链路

有了之前所描述的系统支撑后,新代码上线后的灰度验证将变得非常简单和安全。

由于达达的业务特点,每一次新功能的上线都可能涉及多个服务的更新。但是在链路系统出现之前,我们完全没办法隔离验证多个灰度服务之间的调用。而现在,我们只需要从每一个服务中选择一个节点拉入灰度链路,就可以保证进入灰度入口的流量只会在灰度链路中流转,从而,统一隔离验证多个灰度服务就变成了一件轻松的事情。

在真实场景中,我们将灰度链路定义为“弱链路”:即使任何一个灰度节点不可用,流量也会返回到基础链路中(而非中断请求),所以不会对线上业务造成任何影响。

压力测试链路

对于压力测试,我们现在只需要通过Director将线上环境中的部分节点隔离出来并将他们组成一条压测链路即可。整个操作过程在一小时内即可安全完成,相比之前单独搭建完整的压测环境,效率提升了百倍有余。

值得注意的是,因为压力测试的特点,我们必须完全杜绝任何的压测流量进入到生产环境中,以免对线上系统和终端用户产生影响。所以我们将压力测试链路定义为“强链路”:如果任何压测链路上的服务节点完全不可用,那么流量会中断于压测链路之中,而不会回到基础链路,从而不会对线上业务产生任何影响。

并行功能测试

想必大家都经历过多个需求同时被开发测试的场景。在没有链路隔离系统之前,我们的单个服务只可能有一个版本存在于测试环境之中,导致不同测试同学之间会竞争同一资源,场面非常混乱,严重影响测试效率。而现在,每个测试同学只需要拉取一条完全属于自己的链路,即可独立测试各自需求,做到互不干扰。

其它

链路隔离系统实现简单,概念易于理解,但是功能强大,可应用的场景非常之多。它不只是我们服务治理体系的一个简单扩展,更为我们未来的业务发展和需求提供了无限的可能性,譬如多机房多活测试和线上降级演练等。目前链路隔离系统已成为达达内部服务治理的一把利刃,高效的解决了我们之前难以解决的很多疑难场景,已被达达的所有研发部门广泛使用。

鸣谢

在整个项目的设计开发和推进过程中,也得到了来自达达研发内部多个项目组的大力支持和帮助。尤其特别感谢来自测试组的 刘芹程昊 同学,为我们整个项目的质量提供了强有力的保证。感谢来自业务后端组的 杨玉才 同学,没有他的协助,我们的项目不可能推进的如此顺利。感谢来自运维的 周枫 同学,他为我们consul的发布和标准化部署提供了很大的帮助。最后感谢基础架构组的 魏智博 ,他为整个项目的功能设计和本篇文章的成型花费了很多的心血。

ziEVf2n.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK