用户维度的灰度方案

背景

在日常开发中,当修改了一些核心代码,或遇到测试环境难以完全覆盖的场景时,我们希望在上线时能通过灰度逐步放量来验证新逻辑。这样一来,如果发现问题,也可以快速切换回旧逻辑。

下面我就介绍下,一个简单的基于用户维度的灰度的方式。

整体流程

简单的流程如下:

处理逻辑:

接收到用户请求后,系统会根据用户标识和灰度配置规则进行处理,判断该用户是否被灰度。如果用户被灰度,则执行新的代码逻辑;如果未被灰度,则执行旧的代码逻辑。

灰度配置规则的存储

  1. 配置中心,使用的时候直接读取配置中心的配置,修改灰度的配置的时候,配置中心也可以快速的推到应用中,快速生效配置。
  2. 数据库+缓存,使用的时候从数据库中将配置加载到缓存中,读取缓存的灰度配置的数据,使用数据库+缓存的方式,修改灰度配置的时候要复杂一点,先去修改数据库里面的配置,再去删掉缓存中的数据。

灰度配置规则的处理

灰度配置处理逻辑

java 复制代码
     public boolean isGray(Long userId) {

        if (userId == null) {
            return false;
        }

        try {
		        // 灰度配置规则可以从 apollo 或者从缓存中取,根据实际情况 获取gray_config
            String rule = config.getProperty("gray_config", "");

            if (StringUtils.isEmpty(rule)) {
                return false;
            }

            JSONArray objects = JSON.parseArray(rule);

            if (CollectionUtils.isEmpty(objects)) {
                return false;
            }
            for (Object object : objects) {

                JSONObject jsonObject = (JSONObject) object;
                String type = jsonObject.getString("type");

                if (StringUtils.isEmpty(type)) {
                    continue;
                }

                if ("direct".equals(type)) {
                    String userIds = jsonObject.getString("data");
                    Set<String> userIdSet = StringUtils.commaDelimitedListToSet(userIds);
                    if (userIdSet.contains(String.valueof(userId))) {
                        return true;
                    }
                }

                if ("mod".equals(type)) {
                    Integer scale = jsonObject.getInteger("data");
                    if (scale < 0) {
                        continue;
                    }
                    if (scale >= 100) {
                        return true;
                    }

                    Integer remainder = (int) (userId % 100);
                    if (remainder <= scale) {
                        return true;
                    }
                }

            }
        }
        catch (Exception ex) {
            logger.error("处理灰度失败", ex);
        }
        return false;
    }

用户配置规则gray_config可以如下配置

java 复制代码
[
    {
        "type": "mod",
        "data": "10"
    },
    {
        "type": "direct",
        "data": "10001,10002"
    }
]

上述灰度配置表示的含义如下:

第一个配置:使用用户 ID 与 100(可自定义)取模。当取模后的值大于等于 0 且小于 10 时,表示该用户被灰度。如需扩大灰度范围,可以将 data 值调大,直到大于等于 100 时实现全量放开。当 data 值小于 0(如 -1)时,则为全量关闭。

第二个配置:将用户 ID 与指定的用户 ID 列表进行对比。如果用户 ID 存在于该列表中,则表示该用户被灰度;反之则未被灰度。

mod 和 direct 均可配置多条规则,只要满足其中任一规则,即视为通过灰度校验。

总结

以上介绍了一个简单的用户维度的灰度方案,可以灵活指定用户灰度或者按照比例对用户进行灰度。

这个用户比例计算也是一个大致的范围,可能有数据倾斜,不过总体还是能反应用户的分布的。

最后当灰度完成后,需要将旧代码删除。

相关推荐
海风极客3 分钟前
《Go小技巧&易错点100例》第三十一篇
开发语言·后端·golang
бесплатно7 分钟前
Scala流程控制
开发语言·后端·scala
爱吃烤鸡翅的酸菜鱼24 分钟前
Java【网络原理】(5)深入浅出HTTPS:状态码与SSL/TLS加密全解析
java·网络·后端·网络协议·http·https·ssl
有梦想的攻城狮1 小时前
spring中的@Qualifier注解详解
java·后端·spring·注解·qualifier
程序员阿鹏2 小时前
Spring Boot项目(Vue3+ElementPlus+Axios+MyBatisPlus+Spring Boot前后端分离)
java·前端·vue.js·spring boot·后端·spring·maven
一勺菠萝丶3 小时前
深入浅出:Spring Boot 中 RestTemplate 的完整使用指南
java·spring boot·后端
海风极客4 小时前
《Go小技巧&易错点100例》第三十二篇
后端·spring·golang
有梦想的攻城狮4 小时前
SpEL(Spring Expression Language)使用详解
java·后端·spring·spel
caihuayuan54 小时前
前端面试2
java·大数据·spring boot·后端·课程设计
郭尘帅6665 小时前
SpringBoot学习(上) , SpringBoot项目的创建(IDEA2024版本)
spring boot·后端·学习