使用 Go&MurmurHash&JsonLogic 实现前端资源灰度分流

一、背景

在日常的前端开发中,倘若想验证一个业务功能正向性,需要针对部分用户进行灰度实验。

二、解决方案

方案 1:中转页

用一个轻量级的 H5 页面做流量中转,收集完用户信息后使用 Ajax 来请求后端接口来判断一个用户是否命中灰度,再通过 location.hreflocation.replace 来做相应的页面跳转。

优点:

  1. 适用于页面结构大不同的多个页面。

缺点:

  1. 两次页面加载页面,极其影响转化率。
  2. 不适用于只是模块小改的页面。

示例:

ajax.get('https://getwhich.com').then(
    abValue => {
        let jumpUrl = 'https://default.com'
        if (abValue === 'iAmExp') {
            jumpUrl = 'https://exp.com'
        }
        location.href = jumpUrl
    }
)

方案 2:JavaScript 分流

在页面渲染的过程中,通过 Ajax 询问用户是否命中灰度,命中灰度则渲染灰度模块。

优点:

  1. 适用于快速迭代的小功能,开发量小。

缺点:

  1. 代码冗余,需要保留原有功能。
  2. 版本混乱,发版频繁的情况下,这段时间将伴随着其他功能的上线,若要排查问题或者回滚往往比较麻烦。
  3. 性能差,渲染前多一层网络请求后的判断。
  4. 维护成本增加,灰度结束后需要重新发版前端项目,以规避分流逻辑造成的损耗。

示例:

ajax.get('https://getwhich.com').then(
    abValue => {
        if (abValue === 'iAmExp') {
            render(ExpDOM)
        } else {
            render(DefaultDOM)
        }
    }
)

方案 3:Nginx 分流

在服务器代理层就进行转发,需要在入口层、运维方和业务方三方配合。

优点:

  1. 网络层面更快,折损极小。

缺点:

  1. 公司运维方往往是比较独立的部门,参与业务开发合作时沟通成本和后期维护成本较高。
  2. 不适用于只是模块小改的页面。

方案 4:后端接口重定向(前端资源)

有点类似于 Nginx 分流,不过将运维部分的职责转移到了业务后端,将加载前端资源的链接替换成后端接口,在接口层做 302 重定向。

优点:

  1. 性能更好(相对于前端层中转),折损较小。
  2. 更加灵活,可用于分流 HTML、CSS、JavaScript 等资源。
  3. 维护成本低,回滚快,数据配置层即可控制分流。

示例:

loadScript('https://to-real-frontend-resource.com')

综上,方案 4 是比较合适的方案,不过后端将承担较重的职责。

三、技术方案

3.1 控制灰度量

MurmurHash 是一种非加密 Hash 算法,对于输入的值输出一个具备分布式的 32 / 64 / 128 位散列值。

/**
 * @method str2Murmur
 * @description 字符串转 Murmur Hash 分布式的百分比 1~100
**/
func str2Murmur (str string, seed int) int {
    murmur2 := MurmurHash2([]byte(str), uint32(seed))
    denominator := math.Pow(2, 32) - 1
    percent := float64(murmur2) / denominator
    percentInt := int(percent * 100) + 1
    return percent, percentInt
}

利用用户标识来生成 32 位的 HASH 值,再以 2^32 - 1 为分母来让其在 1 ~ 100 之间均匀分布来控制灰度的量。

3.2 约束流量准入条件

JsonLogic 是一个约束前端和后端过滤条件的规范,已经有 Golang JsonLogic 库做了开源。

{
    "and": [
        {"==": [{"var": "platform"}, "mm"]},
        {">": [{"var": "v"}, 101]},
        {"==": [{"var": "page"}, "home"]}
    ]
}

以上 JSON 代表着同时满足平台(platform)是 mm、版本(v)大于 101、页面(page)是首页的过滤条件。

发表评论

您的电子邮箱地址不会被公开。