MSE注册配置中心支持灰度发布,即在配置正式发布前先进行小部分的发布验证,降低配置推送的风险。本文介绍如何在MSE上为Nacos实例配置灰度发布。
前提条件
仅MSE Nacos开发版和专业版支持灰度发布功能。
客户端Nacos Client建议使用2.x版本。
背景信息
在使用配置中心对集群配置进行集中管理时,如果对某个配置进行了修改,一般情况下新的配置将会覆盖旧的配置,同时会全量地推送到集群中。这种情况下,由于是全量推送,一旦配置出错,可能会导致整个集群都无法运行,风险极大。
因此,在需要对配置进行编辑时,推荐先进行灰度发布,让集群中一部分机器先收到新版本的配置内容,预先进行功能的验证,如果验证通过,再逐步扩大灰度,直至全量正式发布,降低配置变更风险。
当前MSE Nacos支持两种灰度发布的方式:基于IP地址的灰度以及基于标签灰度的方式。
基于IP地址灰度
Beta发布是指在修改配置之后,首先在指定的一小部分的机器(一般是流量比较低、或者影响较小的机器)上进行Beta配置推送,其他机器依旧使用原本的配置。然后对这一部分集群进行验证测试,运行一段时间后,确定这一部分集群运行没有问题。配置稳定之后,再正式发布进行全量推送。如果配置在验证测试阶段未通过,则可以停止灰度发布,恢复到原本的配置。Beta发布的整个过程如下图所示:
这种通过在小部分机器上验证待发布的配置的方式,可以大大降低配置推送的风险,减少因配置出错导致的故障。
创建Beta配置
登录MSE注册配置中心管理控制台,并在顶部菜单栏选择地域。
在左侧导航栏,选择注册配置中心 > 实例列表。
在实例列表页面,单击目标实例名称。
在左侧导航栏,选择配置管理 > 配置列表。
在目标配置的操作列单击编辑。在编辑配置面板,打开Beta发布开关。
单击IP地址输入框,在IP地址列表中选择待灰度推送的IP地址。
您也可以选择手动输入IP地址,手动输入支持IP地址补全。
说明IP地址指订阅了该配置的机器IP,多个IP用英文逗号(,)分隔。
修改完配置后,单击发布。在配置内容对比对话框中确认历史版本和当前配置,然后单击发布。
查看Beta配置
登录MSE注册配置中心管理控制台,并在顶部菜单栏选择地域。
在左侧导航栏,选择注册配置中心 > 实例列表。
在实例列表页面,单击目标实例名称。
在左侧导航栏,选择配置管理 > 配置列表。
在正在Beta发布的目标配置的操作列单击编辑。
在编辑配置面板,单击BETA页签,查看BETA发布信息。
其他操作
停止Beta发布:在编辑配置的BETA页签中,单击停止灰度,即可取消Beta发布。
发布正式:在编辑配置的BETA页签中,单击发布正式,在弹出的配置内容对比对话框中确认配置信息,单击发布正式,Beta发布将改为正式发布。
基于IP地址的灰度存在以下问题:
在Nacos1.x版本的客户端中,因为经过了一层SLB的中转,服务端无法精准获取客户端的IP地址。
基于K8s的架构,节点的重建可能会导致机器的IP地址变化,导致基于IP的灰度版本失效。
基于应用标签灰度
在MSE Nacos 2.2.3.3及以上版本中,支持基于应用标签灰度的方式进行灰度发布,您可以在客户端对应用节点进行标签设置。
MSE Nacos版本在2.2.3.3及以上支持应用标签灰度,您需要升级引擎版本至2.2.3.3及以上。
开源Nacos-Client版本在2.3.2及以上支持自定义应用标签灰度,您需要升级客户端版本至2.3.2及以上。
通过环境变量注入标签的能力,需升级Nacos-Client至2.4.2及以上。
客户端设置应用标签
您可以通过以下方式设置应用的标签,应用标签为key-value格式。可以通过properties,JVM参数,环境变量三种方式指定。相同key的情况下,默认优先级:properties > JVM参数 > env环境变量,nacos.config.gray.label
是Nacos内置的默认配置灰度标签。
//1.properties形式传入
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, "your endpoint");
properties.put("project.name", "your app name");
properties.put("nacos.config.gray.label","yourgrayname");
//2.JVM参数设置
设置启动参数-Dnacos.config.gray.label=yourgrayname
//3.env环境变量指定
设置环境变量 nacos_config_gray_label=yourgrayname
String dataId = "gray_test_dataid";
String group = "test-group";
configService.addListener(dataId, group, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public void receiveConfigInfo(String configInfo) {
System.out.println("receiveConfig:" + configInfo);
}
});
服务端发布标签灰度
查看监听者标签
客户端完成应用标签注入后,可以通过服务端查看配置的监听者列表,查看每个监听者携带的标签。
发布灰度标签配置
单击编辑配置,选择基于标签灰度发布,然后选择应用节点当前存在的标签键值对,可以看到选择的键值对所匹配到的节点数。
发布灰度标签版本后,在监听查询可以看到当前客户端所匹配的配置版本。在配置详情可以看到当前灰度版本的详情。
在进行第一批灰度观察后,可以通过扩大编辑标签的值范围来逐步扩大灰度,直到进行全量发布,单击全量发布后,将停止对应的灰度版本。如果在灰度过程中发现业务异常,可以单击停止灰度进行一键自动回滚。
相关问题
应用标签设置的进阶用法
除了设置单个标签nacos.config.gray.label
之外,Nacos还支持设置多个标签以及自定义标签Collector SPI的形式来设置标签,支持更加灵活自定义标签获取逻辑。
设置多值标签。
Nacos支持在应用标签中注入多个标签键值对。可以在properties和JVM参数中指定
nacos.app.conn.labels
参数(格式示例:nacos.app.conn.labels="k1=v1,k2=v2,k3=v3"
),或者在环境变量中指定nacos_app_conn_labels参数。//1.properties形式传入 Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, "your endpoint"); properties.put("project.name", "your app name"); properties.put("nacos.app.conn.labels","app=demo,site=hangzhou-c,otherkey=othervaue"); //2.JVM参数设置 设置启动参数-Dnacos.app.conn.labels="app=demo,site=hangzhou-c,otherkey=othervaue" //3.env环境变量指定 设置环境变量 nacos_app_conn_labels="app=demo,site=hangzhou-c,otherkey=othervaue" NacosConfigService configService = new NacosConfigService(properties); String dataId = "gray_test_dataid"; String group = "test-group"; configService.addListener(dataId, group, new Listener() { @Override public Executor getExecutor() { return null; } @Override public void receiveConfigInfo(String configInfo) { System.out.println("receiveConfig:" + configInfo); } });
自定义应用标签SPI
Nacos-Client定义了自定义应用标签的SPI,可以通过实现
com.alibaba.nacos.common.labels.LabelsCollector
接口,并将具体实现类发布为service的方式实现自定义的应用标签SPI。package your.demo.test; import com.alibaba.nacos.common.labels.LabelsCollector; import java.util.HashMap; import java.util.Map; import java.util.Properties; /** * TestLabelsCollector. * * @author yourname */ public class TestLabelsCollector implements LabelsCollector { @Override public String getName() { return "testlables"; } @Override public Map<String, String> collectLabels(Properties properties) { Map<String, String> labels = new HashMap<>(); labels.put("test", "implements your lables logic"); return labels; } @Override public int getOrder() { return 1; } }
应用标签规划
在规划应用节点的标签时,推荐根据业务影响范围的大小维度进行标签规划,以逐步灰度并降低变更风险。以下是常见的最佳实践:
将应用名作为标签。先对部分非关键链路上的应用进行灰度,观察确认无异常之后再扩大灰度至核心链路的应用。
业务侧可以通过流量入口侧对系统上下游的机器进行流量隔离。例如,针对公司内部用户确定一批灰度机器,可以为这部分机器设置单独的灰度标签,以达到内部用户灰度的效果。
应用标签的格式
标签键值key-value允许使用的字符包括英文字母大小写、数字、下划线“_”、横杠“-”和点“.”。如果传入其他格式的标签将被忽略处理。如果通过参数nacos.app.conn.labels
指定多个键值对时,格式必须遵循 "k1=v1,k2=v2,k3=v3"
格式。如果传入"k1=v1,k2"
,那么k2参数将会被忽略,最终解析成k1=v1
。