MSE注册配置中心支持灰度发布,即在配置正式发布前先进行小部分的发布验证,降低配置推送的风险。本文介绍如何在MSE上为Nacos实例配置灰度发布。
前提条件
仅MSE Nacos开发版和专业版支持灰度发布功能。
客户端Nacos Client建议使用2.x版本。
背景信息
在使用配置中心对集群配置进行集中管理时,如果对某个配置进行了修改,一般情况下新的配置将会覆盖旧的配置,同时会全量地推送到集群中。这种情况下,由于是全量推送,一旦配置出错,可能会导致整个集群都无法运行,风险极大。
因此,在需要对配置进行编辑时,推荐先进行灰度发布,让集群中一部分机器先收到新版本的配置内容,预先进行功能的验证,如果验证通过,再逐步扩大灰度,直至全量正式发布,降低配置变更风险。一个标准的配置灰度发布的流程如下图所示:
在配置变更过程中,需要选择灰度节点来进行灰度发布。目前,MSE Nacos支持两种灰度发布的方式:基于IP地址的灰度和基于标签的灰度。
基于IP地址灰度
基于IP的灰度发布是一种基础的灰度方式,可以通过选择IP地址列表来确定需要灰度的机器,在一些小型业务系统中,这种方式可以满足灰度的需求,能够大大降低配置推送的风险,减少因配置出错导致的故障。
创建Beta配置
登录MSE注册配置中心管理控制台,并在顶部菜单栏选择地域。
在左侧导航栏,选择注册配置中心 > 实例列表。
在实例列表页面,单击目标实例名称。
在左侧导航栏,选择配置管理 > 配置列表。
在目标配置的操作列单击编辑。在编辑配置面板,发布方式选择基于IP灰度发布。
单击应用节点 IP输入框,在IP地址列表中选择待灰度推送的IP地址。
您也可以选择手动输入IP地址,手动输入支持IP地址补全。
说明IP地址指订阅了该配置的机器IP,多个IP用英文逗号(,)分隔。
修改完配置后,单击发布灰度。在配置内容对比对话框中确认当前灰度版本内容和本次发布内容,然后单击发布。
查看Beta配置
登录MSE注册配置中心管理控制台,并在顶部菜单栏选择地域。
在左侧导航栏,选择注册配置中心 > 实例列表。
在实例列表页面,单击目标实例名称。
在左侧导航栏,选择配置管理 > 配置列表。
在正在Beta发布的目标配置的操作列单击编辑。
在编辑配置面板,单击Beta(IP)页签,查看Beta(IP)发布信息。
其他操作
停止灰度:在编辑配置的Beta(IP)页签中,单击停止灰度,即可取消Beta发布。
全量发布:在编辑配置的Beta(IP)页签中,单击全量发布,在弹出的配置内容对比对话框中确认配置信息,单击全量发布,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; } }
多灰度版本并行
对于一个配置来说,可能存在多个配置的版本,包括正式版本,基于IP的灰度版本,基于标签的灰度版本,其中基于标签的灰度可以发布多个版本。当一个配置存在多个版本时,Nacos服务端的配置查询及推送将以如下的优先级规则进行匹配。 基于IP的灰度版本>基于标签的灰度版本>正式版本。
在处理多个基于标签的灰度版本时,按照优先级priority字段的值进行排序,优先级priority值越大,优先级越高;如果优先级priority值相等,则按照灰度版本名称进行排序,建议将不同的灰度版本设置明确的优先级。
当设置了一个应用标签的应用节点,优先匹配是否存在针对当前应用节点IP的灰度版本,如果存在,则返回基于IP灰度的配置版本,如果不存在,则尝试按照优先级匹配基于标签的灰度版本,如果匹配成功,则返回对应的配置灰度版本,如果没有匹配的标签灰度版本,则返回当前配置的正式版本。可以在MSE控制台的监听查询界面查看每个应用节点当前所匹配到的配置版本。
MSE Nacos 2.3.0+版本支持多灰度版本并行,对一个配置所发布的最大灰度版本数量有一定限制,默认最大支持5个标签灰度的版本,超过上限时,灰度发布将被拦截。
应用标签规划
在规划应用节点的标签时,推荐根据业务影响范围的大小维度进行标签规划,以逐步灰度并降低变更风险。以下是常见的最佳实践:
将应用名作为标签。先对部分非关键链路上的应用进行灰度,观察确认无异常之后再扩大灰度至核心链路的应用。
业务侧可以通过流量入口侧对系统上下游的机器进行流量隔离。例如,针对公司内部用户确定一批灰度机器,可以为这部分机器设置单独的灰度标签,以达到内部用户灰度的效果。
应用标签的格式
标签键值key-value允许使用的字符包括英文字母大小写、数字、下划线“_”、横杠“-”和点“.”。如果传入其他格式的标签将被忽略处理。如果通过参数nacos.app.conn.labels
指定多个键值对时,格式必须遵循 "k1=v1,k2=v2,k3=v3"
格式。如果传入"k1=v1,k2"
,那么k2参数将会被忽略,最终解析成k1=v1
。