简介:本文介绍了微服务治理下金丝雀发布的能力,解决了发布期间少量流量验证新功能的问题。

前言

本文,我们继续聊聊《揭秘大流量场景下发布如丝般顺滑背后的原因》中的另外一环,灰度发布,也叫金丝雀发布。

很多互联网公司在半夜发布的另外一个重要原因是不具备可灰度能力,新版本存在 bug 或者其它原因会影响线上的客户,无奈之下只能选择在半夜进行发布来减少影响面。

我们知道默认情况下,无论是 Kubernetes 还是 ECS,新老版本都存在的情况下会根据特定的负载均衡算法随机地路由到不同的实例上,随机意味着出问题也会随机出现。我们需要一套动态路由来完成灰度发布的解决方案。

在 RPC 领域,我们称灰度发布为动态路由,动态路由的意思是指流量可以动态地路由到指定的实例上。

动态路由场景

动态路由是微服务里非常核心的功能,流量动态路由意味着可以做非常多的事情。由此衍生出各个场景:

  • 金丝雀发布:只有满足特定规则(比如 Query Parameter、HEADER、COOKIE 中某些 KEY 满足一些条件)或者是固定流量比例的流量才会进入新版本,其它流量都路由到老版本上。

  • 同机房优先路由:当公司规模扩大之后,应用会跨机房部署来达到高可用的目的。由于异地跨机房调用出现的网络延迟问题,需要确保服务消费方能优先调用相同机房的服务消费方,这就需要同机房优先路由的能力。

  • 标签路由:金丝雀发布的新场景。金丝雀发布一般只有新和老两个版本,标签路由可以在线上部署多个版本,每个版本都对于一个标签。

  • 全链路灰度:在业务比较复杂,服务调用链路较长的场景下,每个应用都需要设置路由规则会显得非常繁琐,全链路灰度在金丝雀/标签路由的基础上加上了 "标签透传" 的能力,让灰度流量只在灰度版本之间路由。

接下来我会分几篇文章详细讲一下这几个场景,今天我们先来聊聊金丝雀发布。金丝雀发布可以让我们在白天流量高峰喝着茶吃着瓜子进行线上发布,不需要在半夜为发布的事情而苦恼。

大流量下的应用部署现状

应用 Demo

Demo 以 Spring Cloud 为例,服务调用链路如下图所示:

流量从 Netflix Zuul 对应的 Ingress 进来,会调用 SC-A 应用对应的服务,SC-A 应用内部调用 SC-B 应用的服务,SC-B 应用内部调用 SC-C 应用的服务。SC-A 有线上版本和灰度版本这两个版本。

Helm 部署 Demo

Demo 为纯开源 Spring Cloud 架构,项目地址:https://github.com/aliyun/alibabacloud-microservice-demo/tree/master/microservice-doc-demo/traffic-management。

部署完毕后,阿里云容器服务上的工作负载情况如下:

我们通过 "while true; do curl http://{ip:port}/A/a;echo;done" shell 命令不断地去访问 Spring Cloud 服务,各个服务的作用仅仅是打印当前服务的IP,这样我们可以看到整体调用链路:

while true; do curl http://{ip:port}/A/a;echo;done
A[10.0.0.73] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A[10.0.0.73] -> B[10.0.0.180] -> C[10.0.0.72]
A[10.0.0.73] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A[10.0.0.73] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A[10.0.0.73] -> B[10.0.0.180] -> C[10.0.0.72]
...

从这个过程我们明显可以看出 Netflix Zuul -> SC-A 这条链路是随机访问的,由于 SC-A 的线上版本和灰度版本各只有 1 个 Pod,所以随机打印了这两个 POD 的 IP。

开源金丝雀的实现

动态路由的本质就是寻址过程中去找符合条件的实例地址。

Apache Dubbo 提供了 RouterChain 的能力去过滤 Invoker 列表,RouterChain 内部维护着 Router 列表,每个 Router 都会做过滤 Invoker 的逻辑,最后将 Invoker 列表交付给 LoadBalance 做负载均衡获取最后的 Invoker。

ScriptRouter,ConditionRouter 和 TagRouter 这些内置的 Router 内部都是 Dubbo 自带的动态路由能力。

Spring Cloud 的路由能力由 Ribbon 实现。Ribbon 设计了 ILoadBalancer 接口用于获取 Server 列表,最后将这个列表交付给 IRule 做负载均衡策略获取最后的 Server。这块在设计上跟 Dubbo 相比是有缺陷的。

Spring Cloud Ribbon 里的 ILoadBalancer 相当于是 Dubbo RouterChain 里的一个 Router,IRule 相当于是 Dubbo LoadBalance。

最新版本的 Spring Cloud 新增了 Spring Cloud LoadBalancer 组件代替 Ribbon 用于做负载均衡,Spring Cloud LoadBalancer 里的 ServiceInstanceListSupplier 用于获取实例列表信息,ReactiveLoadBalancer 使用负载均衡策略获取最后的实例。

这是 3 者对应组件的说明:

Apache Dubbo 虽然内置了各种 Router,但实际使用下来却有非常多的问题。比如 TagRouter 跟 IP 绑定,在 Kubernetes 下无法工作;ScriptRouter 用了 ScriptEngine 去做脚本的处理,会有性能问题;Dubbo Admin 的使用体验非常糟糕等等。

Spring Cloud 官方并没有提供动态路由的能力,只有社区上的一些开发者自己去扩展了这个能力,社区上也没有任何的 UI 交互界面。

这时候 MSE 告诉你,MSE 的微服务解决方案提供了动态路由的能力,不需要做任何的代码和配置的修改,就能使用 OPEN API 或者 UI 交互去完成金丝雀发布。只需将您的应用接入 MSE 服务治理,您就能享受到金丝雀能力。

只要你的应用是基于 Spring Cloud 或 Dubbo 最近五年内的版本开发,就能直接使用完整的 MSE 微服务治理能力,不需要修改任何代码和配置。

无需任何代码修改就可以做到动态路由的能力,这不香吗?

MSE 金丝雀能力

应用接入 MSE 即可享受 MSE 提供的动态路由能力,无需任何代码修改。

引入标签概念

MSE 引入了标签的概念,可以针对每个标签设置路由规则,满足该路由规则的流量会路由到这个标签对应的实例下。我们将 Spring Cloud Demo 进行一点改造,给 SC-A 的灰度版本打上 "blue" 标签( Helm 已经完成了这个步骤)。

接入 MSE 后,MSE 默认会给应用分配一个 100% 路由到未打标实例的路由规则。此时,我们继续通过 "while true; do curl http://{ip:port}/A/a;echo;done" shell 命令去执行,这个时候调用 SC-A 全部返回线上版本的 IP:

while true; do curl http://{ip:port}/A/a;echo;done
A[10.0.0.73] -> B[10.0.0.180] -> C[10.0.0.72]
A[10.0.0.73] -> B[10.0.0.180] -> C[10.0.0.72]
A[10.0.0.73] -> B[10.0.0.180] -> C[10.0.0.72]
A[10.0.0.73] -> B[10.0.0.180] -> C[10.0.0.72]
A[10.0.0.73] -> B[10.0.0.180] -> C[10.0.0.72]
...

设置金丝雀路由规则

我们在 MSE 上的应用详情页里的金丝雀 Tab 页里设置 HEADER 里 env 这个 KEY 的值为 test 的金丝雀路由条件:

传入 HEADER 继续使用 shell 执行:

while true; do curl -H "env:test" http://139.196.200.40/A/a;echo;done
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
A1[10.0.0.20] -> B[10.0.0.180] -> C[10.0.0.72]
...

这个时候我们发现满足金丝雀规则的流量都去了 SC-A 的灰度版本。

金丝雀路由规则解析

大家看到金丝雀路由规则界面上有两种分别,分别是流量比例流量规则:

流量规则:表示满足该规则的流量会路由到对应标签(本文使用 blue 作为灰度标签)实例上。比如本文例子中 HEADER 里 env=test 的流量一定会去 blue 标签对应的实例。

流量比例:不满足任何流量规则的流量会按照流量百分比进行路由。比如本文例子中不满足 HEADER 里 env=test 的流量会以 100% 的规则路由到未打标的实例上,由于是 100%,所以那些不满足规则的流量全部都去了未打标实例上(本文未打标表示线上版本)。

MSE 提供的流量规则里的条件支持 HEADER、Query Parameter、COOKIE 以及 Request BODY

Query Parameter、HEADER、COOKIE 和 Request Body 除了支持常规的运算符外,还支持 in(白名单),对 100 取模和百分比。这里的百分比并不是比例规则中的总流量百分比,而是指对应参数的 hash 值取模,这样就可以让固定的值永远满足路由条件(如果按照流量比例,用户 A 这次访问的是线上版本,下次可能会访问灰度版本)。举个例子,如果 HEADER 中带有用户 ID,我让想部分用户永远能够访问灰度实例,这个时候可以对用户 ID 的 hash 值取模去完成(当然,这个也可以通过白名单去操作,白名单的缺点并不随机,需要输入各个名单)。

Request Body 目前支持解析 json 字符串,比如如下字符串:

{  "a": "aa","b": [1,2,3],"c": [{"d": "dd"}],"e": {"f": "ff"}
}

JSON 访问表达式 .a 的值为 aa。
JSON 访问表达式 .b[0] 的值为 1。
JSON 访问表达式 .c[0].d 的值为 dd。
JSON 访问表达式 .e.f 的值为 ff。

总结

本文介绍了微服务治理下金丝雀发布的能力,解决了发布期间少量流量验证新功能的问题。您的应用只需接入 MSE 服务治理,无需任何操作即可享受到动态路由的能力。除了 MSE(微服务引擎),金丝雀发布还被 EDAS、SAE 等云产品集成。

下一篇,我会给大家分享 MSE 全链路灰度能力。

微服务引擎用户交流群

如果您在微服务引擎MSE使用过程中有任何疑问,欢迎您搜索钉钉群号 23371469 加入钉钉群进行反馈。

原文链接:https://developer.aliyun.com/article/781159?

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

如何在大流量场景下云淡风轻地进行线上发布?相关推荐

  1. 大流量场景下如何云淡风轻地进行线上发布?

    简介: 本文介绍了微服务治理下金丝雀发布的能力,解决了发布期间少量流量验证新功能的问题. 前言 本文,我们继续聊聊<揭秘大流量场景下发布如丝般顺滑背后的原因>中的另外一环,灰度发布,也叫金 ...

  2. 揭秘 | 大流量场景下发布如『丝般顺滑』背后的原因

    简介:很多互联网公司半夜发布,只为减小用户影响,出了问题场面可控.MSE服务治理无损下线,保障了发布期间的流量,让您摆脱半夜发布的窘境. 为什么很多互联网公司不敢在白天发布,都选择在半夜发布.要是能摆 ...

  3. 揭秘大流量场景下发布如「丝般顺滑」背后的原因

    为什么很多互联网公司不敢在白天发布,都选择在半夜发布.要是能摆脱半夜发布的窘境,它不香吗?选择在半夜发布无非是为了减少对用户的影响,出了问题影响面可控. 那我们就来谈谈,发布会有哪些问题. 若您的应用 ...

  4. 「高并发」亿级流量场景下如何实现分布式限流?

    分布式限流的关键就是需要将限流服务做成全局的,统一的.可以采用Redis+Lua技术实现,通过这种技术可以实现高并发和高性能的限流. Lua是一种轻量小巧的脚本编程语言,用标准的C语言编写的开源脚本, ...

  5. 【高并发】亿级流量场景下如何实现分布式限流?看完我彻底懂了!!(文末有福利)

    写在前面 在互联网应用中,高并发系统会面临一个重大的挑战,那就是大量流高并发访问,比如:天猫的双十一.京东618.秒杀.抢购促销等,这些都是典型的大流量高并发场景.关于秒杀,小伙伴们可以参见我的另一篇 ...

  6. 大促场景下云通信高可用、稳定性实战

    简介:为了帮助用户更好地了解和使用云通信的产品,秒懂云通信系统课程还在继续中.12月21日的秒懂云通信,阿里云高级技术专家卢彬彬分享了<安全可靠 稳如泰山+揭秘双11背后阿里云通信黑科技> ...

  7. 亿级流量场景下的平滑扩容:TDSQL的水平扩容方案实践

    为帮助开发者更好地了解和学习分布式数据库技术,2020年3月,腾讯云数据库.云加社区联合腾讯TEG数据库工作组特推出为期3个月的国产数据库专题线上技术沙龙<你想了解的国产数据库秘密,都在这!&g ...

  8. 负载均衡续:万亿流量场景下的负载均衡实践

    高并发优化系列文章(持续更新补充) 垂直性能提升 1.1. 架构优化:集群部署,负载均衡 1.2. 本篇内容:万亿流量下负载均衡的实现 上篇基本把负载均衡涉及到的基础都罗列了,那么到了实际场景下,特别 ...

  9. 开源实践 | OceanBase 在红象云腾大数据场景下的实践与思考

    本文将介绍 OceanBase 在红象云腾大数据场景下的落地实践与思考,希望帮助正在探索 OceanBase 的企业用户快速实现 OceanBase 选型与落地. 作者:童小军 红象云腾 (REDOO ...

最新文章

  1. puppet 工作原理
  2. sqlserver安装时尽量少的占用c盘_安装3dmax出现command line option 报错,如何解决
  3. delphi tabsheet多标签自适应宽度_HTML 图像 img 标签
  4. asp 中使用Ftp.exe 上传大文件
  5. .net hbase client--终于浮出水面的轮子
  6. mock 生成在线图片
  7. 倒果汁c语言,水果榨汁补维生素C?这些补维生素的错误别再犯了
  8. C#开发终端式短信的原理和方法 .
  9. 《深入理解计算机系统》速读提问
  10. 如何使用 RootFS 功能删除 Odyssey 越狱
  11. VSS的基本使用操作介绍
  12. struts2通配符的问题的解决
  13. 计算机网络-聊天室的设计与实现
  14. java表达upll导包在哪_用java实现http断点续传.mht 源代码在线查看 - 自己平时从网上搜集的http协议解析文档 资源下载 虫虫电子下载站...
  15. 万豪国际集团与蚂蚁集团达成合作;快手科技一季度收入同比增长23.8%至211亿元 | 美通企业日报...
  16. MNE官网解读《Annotating continuous data》
  17. ACM2021辽宁省赛:CDEFGILM
  18. 如何直观的理解机器学习过拟合和欠拟合?
  19. Android中删除EditText中内容时报SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
  20. Object类的常用方法

热门文章

  1. Python 骚操作!如何让自己在斗图中立于不败之地?
  2. Nature:压榨学生,论资排辈,现行论文作者制度已死
  3. 如何在Windows系统上使用Object Detection API训练自己的数据?
  4. php项目打开快捷方式,PHP_克隆一个新项目的快捷方式,有没想过最土的项目如何快速 - phpStudy...
  5. beego 快速入门
  6. 使用 gitlab 进行代码管理
  7. js条件语句初步练习
  8. HttpHelper之我见
  9. Verilog inout 双向口使用和仿真
  10. @MarkFan 口语练习录音 20140415 [MDL演讲口语录音]