最新发布《数智时代的AI人才粮仓模型解读白皮书(2024版)》,立即领取! 了解详情
写点什么

羽量级实现灵活通用的微服务流量分发

  • 2020-07-13
  • 本文字数:3311 字

    阅读完需:约 11 分钟

羽量级实现灵活通用的微服务流量分发

背景

伴随着业务的飞速发展,达达集团(NASDAQ: DADA) 内部的微服务数量和节点个数也都在不断增长。经历了六年时间,我们也从公司成立最开始的单一大服务,逐步发展到了几百个云服务,几千台云主机的规模。


当业务逻辑和运行环境越来越复杂,简单的服务发现和治理功能已不能满足我们的需求。相信和许多公司一样,一路走来我们碰到了许多问题:


  1. 在线压测流量隔离:我们希望在与生产保持一致的环境下进行完整的压力测试,但是却苦于没有好的办法将线上真实的生产流量与压测流量隔离开来,我们只能选择耗费大量的人力物力来部署一套与生产一模一样的环境,极度影响压力测试的效率。

  2. 同服务并行测试:随着团队扩大,同一业务服务中会有多个功能在被同时开发和测试,但是因为缺乏好的方法将同一服务的不同版本在测试环境中隔离,这些不同功能只能被串行独立测试,严重影响了测试的效率,让产品的迭代周期变长。

  3. 核心服务无法冷热分离:我们有部分的核心服务同时承载着在线的实时业务流量与内部一些离线 job 的查询流量。其中,前者需要保证性能和功能的稳定,而后者的流量一般会消耗很多的计算资源但是对性能没有严苛的要求。在高峰时期,来自后者的流量会因为占用大量资源而对前者的在线流量产生负面影响。

  4. 多服务灰度发布:一些业务的变动往往需要多个微服务系统代码同时更新,而在灰度发布过程中,我们没办法控制新版本的调用方只调用新版本的服务,使得很多问题不能在灰度发布的过程中被发现,全量上线后引发线上故障。

  5. 服务间的限流:在异常场景下,来自一些非核心项目的大量流量可以让核心服务瘫痪。在没有灵活的限流手段之前,我们只能通过紧急扩容和代码修复来解决问题,拉长了事故恢复的时间,给业务带来损失。


要解决以上的痛点,本质上其实是要求我们在微服务体系内部进行(基于服务组,接口等多个维度的)灵活流量分发。

需求与架构设计

我们调研了市面上已有的一些现成解决方案,如阿里巴巴的 Dubbo,但是因为各种原因(如接入成本高昂,以及达达内部微服务的实现语言多样)没办法被我们直接使用。所以我们最终决定自己实现一套通用灵活的服务治理和流量分发引擎。


由于我们的业务服务情况复杂,业务功能的发展和变化非常快,且可分配在这个项目上的工程师资源并不充裕,所以我们从设计初期,就订立了几个大的原则:


  1. 我们希望这套引擎除了可以解决我们自身已经遇到的问题之外,还可以尽量多的覆盖未来可能遇到的各类同质化问题。

  2. 这套引擎的实现应该与与编程语言无关,否则无法适应达达内部复杂多样的应用服务技术栈。

  3. 实现需要轻量,不要引入过多的外部依赖,舍弃不必要的功能。否则工期太长业务等不了,且越复杂的系统,稳定性的风险就越大。


在此之前,我们有一套基于 consul 的服务发现框架,它已经包含了服务发现最核心的功能,只是流量分发的最小粒度只能到服务级别。但是由于 consul 天生拥有 kv 存储和元数据(metadata)更新的能力,使其具备了一定的扩展能力。而一些需要动态变化的路由规则等配置,我们决定利用配置中心的能力来进行存储,以便我们可以实时更新和分发。


基于这些现状和原则,我们对整体系统的架构做出了如下图所示的设计:



  1. 我们最终决定将新功能的所有逻辑做到客户端中,而 consul 服务只用来关心节点的健康状态以及存储元数据(metadata)。这样做的好处是核心的服务发现可以与业务逻辑最大程度的解耦,且对服务端最小限度的修改也使得整体的成本和风险相对可控。

  2. 除 metadata 外,流量分发策略都以配置形式存储在我们的配置中心中,且提供了一系列管理配置工具供用户去查询和修改。这样可以让我们实时灵活的在运行时来管控整个集群中的流量。

详细设计

元数据模型

我们对想要解决的问题做了进一步的抽象后,发现我们只需要对现有的服务注册模型做以下两个维度的扩充,就足以让我们在客户端中实现灵活的控制逻辑来管控流量:


  1. “链路”:在压力测试和灰度测试的场景下,我们需要将多个服务的不同节点组合在一起形成一个虚拟的隔离环境。我们将这个包含多个服务不同节点的容器称为“链路”,如下图所示:



在上面的示例图中,请求可以被分发到两个不同的链路(“链路 A”与“链路 B”)中。在默认情况下,流量只会在同一链路下流转(身处"链路 A"中的服务只会发送请求给"链路 A"中的下游服务)。在达达的真实环境中,除微服务外,我们的数据源以及核心中间件如消息队列等也被纳入了链路管理之中,所以任何请求都可以在一个完整的链路中被处理。


但是在真实场景中,不是所有的链路都会包含完整的微服务拓扑(如在测试环境中,测试人员只需要对需要测试的服务创建一个链路即可)。此时就需要我们根据链路的不同特点和需求,来决定流量(在本链路中找不到下游服务节点的情况下)是否需要被转向至其他链路中。于是我们将“链路”又细分为两种类型:“强链路”(不允许流量转向到其他链路,比如生产链路和压测链路,他们二者之间流量完全不允许互串)与“弱链路”(可以将流量转向至其他链路,比如测试环境中同一服务的不同分支)。


  1. “服务实例分组”:为了解决服务冷热分离等问题,需要我们对同一服务下的实例节点进一步细分为不同的分组。一个典型的场景如下图所示:



在上面的示例图中可以看出,通过对服务 B 的实例节点进行分组后,我们就可以对流量进行灵活的调度和分发了。


以上的元数据信息因为不会经常变动,且都是与实例节点相关的属性,所以我们决定将这些元数据信息作为实例节点的属性,与实例信息一起存储在 consul 中。

路由规则和逻辑

在对实例节点的元数据进行了扩充和完善之后,我们只需要在这些元数据的基础上构建我们自己的路由规则逻辑就可以了。


为了便于扩展以及可以动态分发,我们将路由规则以 json 形式存储于配置中心中。并且为了更便于研发工程师操作和配置,我们还提供了一套在线工具。具体的路由规则举例如下:



在有了定义好的路由规则之后,我们就可以很轻松的在客户端来撰写路由的业务逻辑了,具体路由逻辑如下图所示:



具体来说,在一个请求即将从 A 服务发送到 B 服务之前,需要做如下的逻辑判断才能决定该请求的真正去向:


  1. 根据发送方本机所处的“链路”:默认只会选择和自己处于相同链路的 B 服务节点。如果未找到可用节点,则会根据自身所处链路的强/弱(前一章节有介绍)属性来判断。

  2. 根据发送方自身的服务名,本机的 IP,请求的接口等信息匹配路由规则:如果匹配到规则,则根据该路由规则指定的目标来进行路由。

真实场景应用

结合我们的解决方案,让我们再次回顾一下第一章中描述的各个问题。


通过“链路”这个简单的概念模型,我们可以:


  • 在生产环境中分配隔离一批节点加入到“压测链路”,其作为一个与“线上流量链路”共处于生产环境中的强链路,两者的流量被完美的隔离。

  • 在测试环境中,同一服务的不同开发分支可以被隔离到不同的链路中,使得针对同一服务的并行测试成为可能。

  • 灰度发布过程中,只需要将一同参与发布的服务都加入到灰度链路中,那么就可以确保进入灰度链路的流量只会在灰度的服务中流转。


通过服务实例分组和灵活的路由功能,我们可以通过动态配置规则就可以实时调控集群中的流量,来实现服务冷热分离和限流等。


这套解决方案也给我们的业务提供了巨大的价值。举例来说,通过使用“链路”系统在线上压测中的应用,不但让我们可以完美的在线上真实环境中进行压力测试,同时还极大的缩短了压测环境准备,应用调试等环节所需要的时间,使得我们整个压测流程的资源投入从 2018 年双 11 的 250 人日缩短到了 2019 年双 11 的 70 人日,效率提升了 350%。

总结

针对我们在业务和系统发展中遇到的各类流量调控需求和问题,我们提出了一套简单易懂的数据模型,通过低成本轻量的逻辑实现,使得这些需求和问题得以被非常好地解决。同时这套解决方案因为足够简单通用,让我们在几乎不需要任何扩展的情况下就可以支持未来可能出现的各类流量相关的需求。


这套系统自上线以来,帮公司节约了大量的技术成本,提升了人效,还规避了很多事故可能造成的潜在损失。

团队成员

  • bowl-gu: 达达集团架构师。微服务治理,数据源高可用等模块的负责人

  • doubleMing: 达达集团架构师。主要负责服务治理,数据源高可用等系统的设计开发与维护

  • superbool: 达达集团架构师。主要负责监控报警平台,流量动态路由等系统


2020-07-13 14:173501

评论 9 条评论

发布
用户头像
对于mq这种异步回调能做到隔离吗?
2022-03-24 14:49
回复
用户头像
想知道这个链路是怎么来串起来的呢?如何做到足够灵活?
2022-01-20 13:55
回复
用户头像
superbool大神
2020-07-14 23:11
回复
用户头像
superbool就是传说中的大神
2020-07-14 18:26
回复
用户头像
学习
2020-07-14 18:26
回复
用户头像
真大佬
2020-07-14 18:20
回复
用户头像
学习了
2020-07-14 18:17
回复
用户头像
好高深的赶脚
2020-07-14 15:27
回复
用户头像
好奇这个框架用什么语言或技术解决 【不用dubbo是因为“内部微服务的实现语言多样”】的?以及 羽量级 由来。
2020-07-14 10:40
回复
没有更多了
发现更多内容

兆骑科创双创服务平台,留学生海外创新创业大赛,人才引进

兆骑科创凤阁

MQTT协议详解及v5.0实践——实践类

阿里云AIoT

物联网 调度 网路协议 网络性能优化 网路架构

105份墨天轮“国产化迁移”干货文档汇总(含TiDB、openGauss、上云等)

墨天轮

数据库 阿里云 TiDB 国产数据库 达梦

激动!开启轻量化虚拟直播时代!

IT资讯搬运工

基础+进阶+源码+实战,阿里SpringCloud Alibaba全解手册限时开源~

Java全栈架构师

程序员 面试 微服务 架构师 SpringCloud

2022年中国小微信贷市场发展分析

易观分析

市场分析 小微信贷 易观

离谱了!腾讯数据库专家耗费几个月编写了这份 604 页的 Oracle+MySQL 学习指南手册

了不起的程序猿

Java MySQL JAVA开发 java程序员

B站基于Iceberg+Alluxio助力湖仓一体项目落地实践

Alluxio

B站 iceberg Alluxio 湖仓一体 8月月更

KusionStack 在蚂蚁集团的探索实践 (上)

SOFAStack

开源 技术分享 蚂蚁集团 Kusion kusionstack

打补丁是什么意思?如何快速对云主机批量打补丁?用什么软件?

行云管家

运维 云主机 IT运维 打补丁

画出“伦勃朗光线”:vivo的夜色4K探索之旅

脑极体

企业统一门户 | WorkPlus深度集成,优化企业管理模式

WorkPlus

全网独一份!清华大牛联合众多一线大厂架构师整合的Java面试突击手册开源

程序员小毕

程序员 程序人生 JVM 高并发 java面试

面试半月,阿里三面挂在微服务,我整个人直接麻了

Java永远的神

程序员 微服务 程序人生 Java 面试 架构师

大型LED显示屏怎样做好保养维护

Dylan

LED显示屏 led显示屏厂家

企业即时通讯怎样为企业实现移动办公效率的极致化?

WorkPlus

自从外包干了七年,废了.....!

退休的汤姆

Java 面经 社招 Java工程师 秋招

1 分钟在 Serverless 上部署现代化 Deno Web 应用

阿里巴巴中间件

阿里云 Serverless 云原生

Gitlab 中 Github import 功能存在远程代码执行漏洞

墨菲安全

将 SAP Spartacus 作为 feature module 进行 Lazy Load 延迟加载时遇到的注入错误分析

Jerry Wang

typescript 前端开发 angular Spartacus 8月月更

2022年十大知名堡垒机品牌你真的知道吗?

行云管家

网络安全 数据安全 堡垒机 堡垒机品牌

旺链科技荣登“长三角产业区块链企业30强”!

旺链科技

区块链 产业区块链 创新应用

“似水无形” 的小程序化技术

Speedoooo

小程序 小程序管理平台 轻应用 快应用 小程序平台

本周四晚19:00知识赋能第七期第3课丨OpenHarmony WiFi扫描仪实现

OpenHarmony开发者

OpenHarmony

Docker下Prometheus和Grafana三部曲之一:极速体验

程序员欣宸

Grafana Prometheus 8月月更

SpringBoot 整合 数据库连接池(Druid、HicariCP、C3P0等等)

SpringBoot 2 Druid 8月月更

浅谈 malloc 函数在单片机上的应用

矜辰所致

malloc 内存管理 8月月更

万物皆可集成系列:低代码释放用友U8+深度价值(2)—数据拓展应用

葡萄城技术团队

低代码 用友

MobTech ShareSDK Android端微信分享小程序

MobTech袤博科技

微信小程序 android sdk

业务出海必答题,融云全球通信网络技术挑战破解实践

融云 RongCloud

蛇行矩阵 蛇形填数 回形取数 蛇行系类(C语言详解+图解)

Five

c 算法题 8月月更

羽量级实现灵活通用的微服务流量分发_架构_达达集团架构团队_InfoQ精选文章