golang 开发技巧及代码案例分享Go - Micro微服务

从 0 到 1 实战构建营销投放:基于 Go 的规则引擎 + 灰

2025-11-24  本文已影响0人  代码扳手

双十一刚过去,你是不是还在被各种复杂的优惠券、满减、阶梯折扣规则折磨?
商促活动本是电商最常见、最重要的业务需求,可现实却让人头疼:每次调整规则都得改代码、提需求、打补丁、重新上线,既耗时又容易出错。

更麻烦的是,一旦促销策略设计不当,影响范围不可控,很可能带来成千上万的财务损失。毕竟——涉及钱的事情,从来马虎不得

基于上面的问题,你是否合适的解决方案?今天我们就来彻底解决你的这些顾虑。


传统投放、风控、内容推荐、商品推荐系统常常面临两个核心难题:

本文带你一步步从零实现一个开箱可用的「规则引擎 + 灰度发布系统」,采用:

不仅讲原理,还提供完整可运行源码结构,是你构建实际生产级策略平台的最佳指南。


🚀 一、为什么要用到 “规则引擎 + 灰度发布” ?

在营销投放、推荐系统、内容分发、风控系统等真实业务中,我们常常需要根据用户画像及行为或事件执行相应的规则。

例如:

但传统方式存在几个痛点:

痛点 描述
💣 规则逻辑硬编码 每次改规则都需要发版,贻误战机
🐌 发布流程慢 回归测试、上线、验证时间长
🌀 无法灰度验证 直接上线,风险巨大
🚫 下发方式不统一 分布式节点同步困难
🔍 可观测性弱 无法知道规则执行情况

为解决这些问题,一个现代策略平台应当具备:

下图展示我们整套系统架构:

┌──────────────┐        ┌─────────────┐
│   Dashboard   │  POST  │  Publisher  │
│(规则配置中心)│   ───▶ │(灰度规则下发)│
└──────────────┘        └───────┬─────┘
                                 │ Kafka
                                 ▼
                          ┌────────────┐
                          │    Edge     │
                          │(规则执行器)│───▶ Webhook Server
                          └────────────┘
                               ▲ Redis
                               │(规则缓存 + 限流)

🧠 二、结合实用案例核心能力拆解

规则编译:CEL 表达式

CEL 是 Google 开源的表达式语言,语法简单、安全可控、性能极高(比 Lua 快 5~20 倍),是你不二的选择。

示例规则:

给注册 30 天内、0 下单、风控评分 < 0.3 的新用户发一张 20 元优惠券,并仅灰度 10% 进行,先在10%范围内测试,效果测试成功后直接修改灰度

{
  "id":"rule_notify",
  "version":"v1",
  "enabled":true,
  "condition":"user[\"register_days\"] < 30 && user[\"order_count\"] == 0 && ml[\"score\"] < 0.3",
  "action":{"type":"call_webhook","params":{"url":"http://webhook-server:9090/coupon"}},
  "strategy":{"type":"percentage","percentage":10},
  "limit_per_second": 100
}

Edge 侧使用 CEL 编译:

env, _ := cel.NewEnv(
    cel.Variable("user", cel.MapType(cel.StringType, cel.DynType)),
)

ast, _ := env.Compile(rule.Filter)
prog, _ := env.Program(ast)

out, _, _ := prog.Eval(map[string]interface{}{
    "user": userInfo,
})

灰度发布机制

Publisher 会按如下方式下发规则:

Publisher 发布营销策略,Publisher 推送后,所有 Edge 节点 5 秒内收到策略更新并生效

msg := RuleMessage{
    RuleID: "rule_notify",
    Expr: `user.register_days < 30 &&
           user.order_count == 0 &&
           ml.score < 0.3 &&
           (region == "CN" || region == "HK")`,
    GrayPercent: 10,
    LimitPerSec: 100,
    ActionURL: "http://webhook-server:9090/coupon",
}

value, _ := json.Marshal(msg)
writer.WriteMessages(ctx, kafka.Message{Value: value})

Kafka 是天然的规则广播管道,所以这里选择了Kafka。当然这里还是又很多其他的选择,你在开发过程中可以按照需求及自身资源进行合理的选择。


Edge 本地规则执行器

当用户打开 App → 请求 Edge 时的执行逻辑为:

// 1. 灰度命中?
if !HitGray(rule.GrayPercent, user.ID) {
    return "SKIPPED_GRAY"
}

// 2. 规则表达式满足?
matched, err := rule.Program.Eval(vars)
if err != nil || !matched {
    return "SKIPPED_EXPR"
}

// 3. 限流检查(Redis Token Bucket)
if !TokenBucketAllow(rule.RuleID, rule.LimitPerSec) {
    return "LIMITED"
}

// 4. 执行动作(Webhook)
CallWebhook(rule.ActionURL, vars)

return "MATCHED"

注意第三步:在营销投放中限流非常关键,因为:


Webhook 动作执行器

Webhook Server 是业务处理端:

命中规则后 Edge 会调用:

http.Post(rule.ActionURL, "application/json", bytes.NewBuffer(body))

用于:

Webhook 服务可按需扩展。


Dashboard 可视化报表整理端

这里因为实际因素没有详细的去做,营销活动的运营数据这是在商促中非常重要的环节,不可能每次都要让一个程序员去后台拉取数据去做”普通文员“的活吧。

// 发送POST请求到边缘节点进行规则评估
resp, err := client.Post(edge+"/eval/rule_notify", "application/json", bytes.NewReader(b))
status := "ERROR"
if err == nil {
// 读取响应体
    body, _ := ioutil.ReadAll(resp.Body)
    resp.Body.Close()

// 解析响应JSON
var er map[string]interface{}
    _ = json.Unmarshal(body, &er)

// 根据响应结果确定状态
if m, ok := er["matched"].(bool); ok && m {
if e, ok2 := er["error"].(string); ok2 && e != "" {
            status = "LIMITED"
        } else {
            status = "MATCHED"
        }
    } else {
// 更详细地处理未匹配的情况
if e, ok := er["error"].(string); ok && e == "rule not found" {
            status = "NO_RULE"
        } else {
            status = "SKIPPED"
        }
    }
}

整个架构的优势:

这一个完整的营销投放系统就这么搭好了。该项目源码具备生产级,需要的朋友可以简单修改就可以直接使用。

在线上营销过程中你是否遇到类似的问题,你的解决方案是什么呢?欢迎在评论区留言讨论。


🔗 源码下载

👉 GitHubhttps://github.com/louis-xie-programmer/rule-engine-gray

👉 Giteehttps://gitee.com/louis_xie/rule-engine-gray

上一篇 下一篇

猜你喜欢

热点阅读