配置灰度发布

MSE注册配置中心支持灰度发布,即在配置正式发布前先进行小部分的发布验证,降低配置推送的风险。本文介绍如何在MSE上为Nacos实例配置灰度发布。

前提条件

说明
  • 仅MSE Nacos开发版和专业版支持灰度发布功能。

  • 客户端Nacos Client建议使用2.x版本。

背景信息

在使用配置中心对集群配置进行集中管理时,如果对某个配置进行了修改,一般情况下新的配置将会覆盖旧的配置,同时会全量地推送到集群中。这种情况下,由于是全量推送,一旦配置出错,可能会导致整个集群都无法运行,风险极大。

因此,在需要对配置进行编辑时,推荐先进行灰度发布,让集群中一部分机器先收到新版本的配置内容,预先进行功能的验证,如果验证通过,再逐步扩大灰度,直至全量正式发布,降低配置变更风险。一个标准的配置灰度发布的流程如下图所示:

f2156f564dbe73b3112eabba0abd5de1

在配置变更过程中,需要选择灰度节点来进行灰度发布。目前,MSE Nacos支持两种灰度发布的方式:基于IP地址的灰度和基于标签的灰度。

基于IP地址灰度

基于IP的灰度发布是一种基础的灰度方式,可以通过选择IP地址列表来确定需要灰度的机器,在一些小型业务系统中,这种方式可以满足灰度的需求,能够大大降低配置推送的风险,减少因配置出错导致的故障。

创建Beta配置

  1. 登录MSE注册配置中心管理控制台,并在顶部菜单栏选择地域。

  2. 在左侧导航栏,选择注册配置中心 > 实例列表

  3. 实例列表页面,单击目标实例名称。

  4. 在左侧导航栏,选择配置管理 > 配置列表

  5. 在目标配置的操作列单击编辑。在编辑配置面板,发布方式选择基于IP灰度发布

    Beta发布

  6. 单击应用节点 IP输入框,在IP地址列表中选择待灰度推送的IP地址。

    您也可以选择手动输入IP地址,手动输入支持IP地址补全。

    说明

    IP地址指订阅了该配置的机器IP,多个IP用英文逗号(,)分隔。

  7. 修改完配置后,单击发布灰度。在配置内容对比对话框中确认当前灰度版本内容本次发布内容,然后单击发布

查看Beta配置

  1. 登录MSE注册配置中心管理控制台,并在顶部菜单栏选择地域。

  2. 在左侧导航栏,选择注册配置中心 > 实例列表

  3. 实例列表页面,单击目标实例名称。

  4. 在左侧导航栏,选择配置管理 > 配置列表

  5. 在正在Beta发布的目标配置的操作列单击编辑

  6. 编辑配置面板,单击Beta(IP)页签,查看Beta(IP)发布信息。

    BETA

其他操作

  • 停止灰度:在编辑配置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);
        }
 });

服务端发布标签灰度

  • 查看监听者标签

    客户端完成应用标签注入后,可以通过服务端查看配置的监听者列表,查看每个监听者携带的标签。

    image.png

  • 发布灰度标签配置

    单击编辑配置,选择基于标签灰度发布,然后选择应用节点当前存在的标签键值对,可以看到选择的键值对所匹配到的节点数。image.png

发布灰度标签版本后,在监听查询可以看到当前客户端所匹配的配置版本。在配置详情可以看到当前灰度版本的详情。

在进行第一批灰度观察后,可以通过扩大编辑标签的值范围来逐步扩大灰度,直到进行全量发布,单击全量发布后,将停止对应的灰度版本。如果在灰度过程中发现业务异常,可以单击停止灰度进行一键自动回滚。

相关问题

应用标签设置的进阶用法

除了设置单个标签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控制台的监听查询界面查看每个应用节点当前所匹配到的配置版本。

3a6b4c74fa088ee7d55e4f83a2cc04d8

说明

MSE Nacos 2.3.0+版本支持多灰度版本并行,对一个配置所发布的最大灰度版本数量有一定限制,默认最大支持5个标签灰度的版本,超过上限时,灰度发布将被拦截。

应用标签规划

在规划应用节点的标签时,推荐根据业务影响范围的大小维度进行标签规划,以逐步灰度并降低变更风险。以下是常见的最佳实践:

  • 将应用名作为标签。先对部分非关键链路上的应用进行灰度,观察确认无异常之后再扩大灰度至核心链路的应用。

  • 业务侧可以通过流量入口侧对系统上下游的机器进行流量隔离。例如,针对公司内部用户确定一批灰度机器,可以为这部分机器设置单独的灰度标签,以达到内部用户灰度的效果。

应用标签的格式

标签键值key-value允许使用的字符包括英文字母大小写、数字、下划线“_”、横杠“-”和点“.”。如果传入其他格式的标签将被忽略处理。如果通过参数nacos.app.conn.labels指定多个键值对时,格式必须遵循 "k1=v1,k2=v2,k3=v3" 格式。如果传入"k1=v1,k2",那么k2参数将会被忽略,最终解析成k1=v1