本文介绍Spring Cloud及Dubbo应用如何按泳道灰度策略进行金丝雀发布。
背景信息
K8s类型应用支持按泳道灰度策略进行金丝雀发布。基于全链路流控泳道的环境隔离机制,在应用灰度发布过程中,被添加至灰度泳道的灰度分批实例将与基线版本实例隔离。只有满足流控泳道入口规则的流量才会被发送至泳道中的灰度分批实例中。
在相同微服务空间下,多个应用支持同时发布至同一泳道。满足泳道入口规则的流量将被染色,并在泳道中全链路透传,以实现全链路灰度控制。
泳道流控规则为避免流量中断,默认存在Fallback策略:
当满足泳道流控规则的流量没有对应灰度服务提供者时,流量会Fallback至基线。
当不满足泳道流控规则的流量没有对应基线服务提供者时,流量会Fallback至灰度。
Spring Cloud应用进行金丝雀泳道发布
前提条件
已在EDAS控制台部署完成本示例的四个应用:Zuul网关应用、应用A、应用B和应用C,且每个应用副本数≥2。具体操作,请参见创建和部署应用概述(K8s)。
步骤一:创建泳道组
登录EDAS控制台。
在左侧导航栏,选择 。
在全链路流量控制页面顶部菜单栏选择地域,在页面中选择目标微服务空间,然后单击创建。
在创建泳道组对话框中设置泳道组相关参数,然后单击确定。
步骤二:创建泳道
选择并切换至步骤一:创建泳道组中创建好的泳道组,并单击点击创建第一个分流泳道。
在创建流控泳道面板中配置相关参数后,单击确定。
入口规则本示例设置为基于
Header
的条件,当存在tag
为grey
时,流量进入灰度泳道。接收打标流量应用中无需添加应用,应用与泳道的关联由应用的金丝雀发布策略托管。
步骤三:应用按泳道策略进行金丝雀发布
步骤四:配置确认
在变更记录页面查看当前灰度批次及灰度泳道配置。
在流量管理 > 微服务治理 > 全链路流量控制页面,可以看到应用的灰度批次已经加入指定泳道。
步骤五:流量验证
在应用总览页面的基本信息区域,单击运行状态右侧的点击查看,查看灰度批次实例IP地址。
在应用配置详情面板,单击Zuul应用的终端进入本地IP,发送灰度流量。
for i in {1..10}; do curl -H "tag: grey" http://47.111.XX.XX/sc-A/a ;sleep 0.1; echo ""; done Agrey[10.14.2.95] -> Bgrey[10.14.1.224] -> C[10.14.1.220] Agrey[10.14.2.95] -> Bgrey[10.14.1.224] -> C[10.14.1.220] Agrey[10.14.2.95] -> Bgrey[10.14.1.224] -> C[10.14.1.220] Agrey[10.14.2.95] -> Bgrey[10.14.1.224] -> C[10.14.1.220] Agrey[10.14.2.95] -> Bgrey[10.14.1.224] -> C[10.14.1.220] Agrey[10.14.2.95] -> Bgrey[10.14.1.224] -> C[10.14.1.220] Agrey[10.14.2.95] -> Bgrey[10.14.1.224] -> C[10.14.1.220] Agrey[10.14.2.95] -> Bgrey[10.14.1.224] -> C[10.14.1.220] Agrey[10.14.2.95] -> Bgrey[10.14.1.224] -> C[10.14.1.220] Agrey[10.14.2.95] -> Bgrey[10.14.1.224] -> C[10.14.1.220]
在应用配置详情面板,单击Zuul应用的终端进入本地IP,发送非灰度流量。
for i in {1..10}; do curl http://47.111.XX.XX/sc-A/a ;sleep 0.1; echo ""; done A[10.14.1.214] -> B[10.14.2.92] -> C[10.14.1.220] A[10.14.1.214] -> B[10.14.2.92] -> C[10.14.1.220] A[10.14.1.214] -> B[10.14.2.92] -> C[10.14.1.220] A[10.14.1.214] -> B[10.14.2.92] -> C[10.14.1.220] A[10.14.1.214] -> B[10.14.2.92] -> C[10.14.1.220] A[10.14.1.214] -> B[10.14.2.92] -> C[10.14.1.220] A[10.14.1.214] -> B[10.14.2.92] -> C[10.14.1.220] A[10.14.1.214] -> B[10.14.2.92] -> C[10.14.1.220] A[10.14.1.214] -> B[10.14.2.92] -> C[10.14.1.220] A[10.14.1.214] -> B[10.14.2.92] -> C[10.14.1.220]
Dubbo应用进行金丝雀泳道发布
操作流程
预期效果
应用A按特定判断条件进行分发,满足特定条件的流量会被转发至应用B的灰度批次,并透传至相同泳道中的其他应用灰度批次。
使用限制
由于目前泳道入口规则基于HTTP协议设定,所以泳道规则对于Dubbo协议间的调用不会生效。
应用的灰度分批选择及添加至泳道,实际上是为当前应用的灰度分批实例打标签。所以,流量识别并染色需自行注入流量标签。
步骤一:创建泳道组
登录EDAS控制台。
在左侧导航栏,选择 。
在全链路流量控制页面顶部菜单栏选择地域,在页面中选择目标微服务空间,然后单击创建。
在创建泳道组对话框中设置泳道组相关参数,将上述流量链路中涉及的应用添加至泳道组涉及所有应用中,然后单击确定。
步骤二:创建泳道
选择并切换至已创建的泳道组,单击点击创建第一个分流泳道。
在创建流控泳道面板中配置相关参数后,单击确定。
对于Dubbo协议的服务,泳道入口规则无实际效果,故填写任意条件即可。
接收打标流量应用中无需添加应用,应用与泳道的关联由应用的金丝雀发布策略托管。
在全链路流量控制页面,查看创建的流控泳道。
步骤三:消费端应用流量标注入
本示例中为应用A。
在程序
pom.xml
中引入以下依赖。<dependency> <groupId>com.alibaba.arms.apm</groupId> <artifactId>arms-sdk</artifactId> <version>1.7.3</version> </dependency>
在代码中增加流量判断条件,并实现流量标注入。
public String test(String param) { if ("grey".equals(param)) { injectGreyTrafficTag(); } return demoService.echo(param); } // 注意:此处的laneTag替换为创建泳道时设置的泳道标,其他配置不变。 private void injectGreyTrafficTag() { String laneTag = "testbaggage"; Span span = Tracer.builder().getSpan(); Map<String, String> baggageItems = span.baggageItems(); JSONObject tag = new JSONObject(); tag.put("name", laneTag); tag.put("priority", 100); baggageItems.put("__microservice_tag__", JSONObject.toJSONString(Arrays.asList(tag))); baggageItems.put("cs", laneTag + "(DEFAULT)"); span.withBaggage(baggageItems); }
步骤四:应用按泳道策略进行金丝雀发布
登录EDAS控制台。
在左侧导航栏,选择应用管理 > 应用列表,单击需要进行金丝雀发布的应用名称,如本示例中的应用B、应用C。
在应用总览页面右上角,选择部署 > 部署。
在选择部署模式页面,选择金丝雀发布(灰度),并单击开始部署。
在发布策略区域,单击按泳道灰度,切换至泳道策略选择框。
(可选)新建泳道发布策略需单击添加策略。
在添加泳道灰度策略面板,选择已创建好的泳道组和泳道,单击确定。配置项信息,请参见c.设置灰度规则。
说明只有添加至泳道组中的应用,才支持选择泳道组及其泳道。
在选择策略框,选择已创建的发布策略,然后单击确定,触发应用进行金丝雀发布。
步骤五:配置确认
在变更记录页面查看当前灰度批次及灰度泳道配置。
在流量管理>微服务治理>全链路流量控制页面,可以看到应用的灰度批次已经加入指定泳道。
步骤六:流量验证
在应用总览页面的基本信息区域,单击运行状态右侧的点击查看,查看灰度批次实例IP地址。
在应用配置详情面板,单击操作列的终端,发送灰度流量。
for i in {1..10}; do curl http://127.0.0.1:8088/traffic?param=grey;sleep 0.1; echo ""; done A[10.14.1.213] -> B[10.14.1.210] -> C[10.14.1.212] A[10.14.1.213] -> B[10.14.1.210] -> C[10.14.1.212] A[10.14.1.213] -> B[10.14.1.210] -> C[10.14.1.212] A[10.14.1.213] -> B[10.14.1.210] -> C[10.14.1.212] A[10.14.1.213] -> B[10.14.1.210] -> C[10.14.1.212] A[10.14.1.213] -> B[10.14.1.210] -> C[10.14.1.212] A[10.14.1.213] -> B[10.14.1.210] -> C[10.14.1.212] A[10.14.1.213] -> B[10.14.1.210] -> C[10.14.1.212] A[10.14.1.213] -> B[10.14.1.210] -> C[10.14.1.212] A[10.14.1.213] -> B[10.14.1.210] -> C[10.14.1.212]
在应用配置详情面板,单击操作列的终端,发送非灰度流量。
for i in {1..10}; do curl http://127.0.0.1:8088/traffic;sleep 0.1; echo ""; done A[10.14.1.213] -> B[10.14.2.51] -> C[10.14.1.251] A[10.14.1.213] -> B[10.14.2.51] -> C[10.14.1.251] A[10.14.1.213] -> B[10.14.2.51] -> C[10.14.1.251] A[10.14.1.213] -> B[10.14.2.51] -> C[10.14.1.251] A[10.14.1.213] -> B[10.14.2.51] -> C[10.14.1.251] A[10.14.1.213] -> B[10.14.2.51] -> C[10.14.1.251] A[10.14.1.213] -> B[10.14.2.51] -> C[10.14.1.251] A[10.14.1.213] -> B[10.14.2.51] -> C[10.14.1.251] A[10.14.1.213] -> B[10.14.2.51] -> C[10.14.1.251] A[10.14.1.213] -> B[10.14.2.51] -> C[10.14.1.251]