前言
在一个阳光明媚的早晨,小明收到了一个普普通通的需求,但上需求里面有一个不普通的地方,就是对该功能进行灰度放量,希望一开始只是给目标名单的用户看到这个功能,后续逐渐放开这个功能。
小明这时候就心血来潮,想趁着这个需求顺便搭一个灰度系统,由于是在日常需求中插入的基建,时间紧任务重,所以这个灰度体检要尽量简单。
整体概览
实现一套可根据设置的灰度比例和灰度名单人员进行灰度放量的接口和管配置界面
- 多平台:由于提供了灵活的灰度接口形式,团队内部的小程序、管理端、企微端都可以灵活接入
- 自定义灰度字段:该灰度体系的灰度判断值由接口自行传入,不依赖登录的userId,有着更为灵活多样化的能力
- 辅助信息内容配置:灰度接口也可以支持附带的json信息,以方便具体业务功能的使用
具体实现
相关数据表设计
下面先列出所需要的数据表的结构,一张是存储一些基本的灰度信息的表gray_config,另一张上存储哪些用户是在百白名单的表
灰度配置的主表 gray_config
| 键值 | 名称 |
|---|---|
| id | 主键 |
| gray_key | 灰度键值 |
| gray_rate | 灰度比例 |
| name | 灰度项名称 |
| comment | 灰度信息备注 |
| extra_info | 灰度额外信息 |
灰度配置的白名单表 gray_whitelist
| 键值 | 名称 |
|---|---|
| id | 主键 |
| gray_id | 灰度配置id,作为上一个表的关联键值 |
| gray_str | 灰度目标值, 可填入userId,手机号等 |
| comment | 灰度白名单信息备注 |
核心流程
- 先判断有没有对应的灰度项, 没有该灰度key值直接抛出错误
- 如果灰度放量设置为100, 直接返回true
- 如果匹配灰度人员名单, 那直接返回true
- 最后对灰度值进行一个hash, 最后归并到0~99的数值, 与管理端配置的阈值比较, 如果小于配置的值则返回为true
灰度hash算法的实现
灰度算法的主要核心思路是将目标的灰度值hash到一个0~99的数值,由于是根据入参进行的灰度计算,也符合用户一次命中灰度,相同灰度条件下也会再次命中的效果
/**
* 判断这个字符串是否命中
* @param str 要hash的数据
* @param threshold 阈值
* @returns
*/
whetherMatch(str: string, threshold: number) {
// 使用node的crypto模块
const hash = crypto.createHash('sha256');
// 更新哈希对象的数据
hash.update(str);
// 获取哈希的十六进制表示
const hashHex = hash.digest('hex');
// 将哈希结果映射到0到100的范围
let hashVal = parseInt(hashHex, 16);
let res = 0;
while (hashVal > 0) {
res = (res + hashVal) % 100;
hashVal = Math.round(hashVal / 100);
}
return res < threshold;
}
管理端配置的实现
这个灰度系统还需要实现一些常规的接口对灰度配置以及白名单进行一个增删改查,以及相应的管理端配置界面给管理人员操作,如下图片所示,实现比较常规,这里就不做赘述
前端调用
前端使用的话只需传入灰度key值和判断灰度的gray_str,这里特意说一下为啥不叫user_id,因为用来判断灰度的虽然大部分情况下说user_id,但也可以是其它的,例如地区等,所以名字起通用一点
总结
经过一番埋头苦干,小明终于把一个简单的灰度系统搭建好了,赶紧和大家分享一下,如果有值得优化的地方,希望大家不吝评论哈