应通过可配置策略实现推送渠道自动路由:定义routestrategy接口,按业务场景标识(如"order_paid")注册不同实现类,避免硬编码和if-else堆积;路由层需低延迟,仅允许查缓存并设默认兜底;灰度与ab测试通过routercontext(含traceid、version、abgroup)结合配置中心动态调控,禁用代码内写死逻辑。

推送渠道怎么根据业务类型自动选微信还是短信
直接看决策逻辑:不能硬编码写死渠道,得把路由规则做成可配置的策略。核心是定义一个 RouteStrategy 接口,每个实现类封装一类判断逻辑,比如按 eventType、userId 段、或用户偏好字段来分发。
常见错误是把所有 if-else 塞进一个函数里,后续加新渠道(如邮件、AppPush)就得改主逻辑,容易漏掉分支或破坏原有行为。
- 推荐用 map[string]RouteStrategy 注册不同策略,key 是业务场景标识(如
"order_paid"、"login_verify") - 策略实现里避免查 DB 或调远程服务——路由层必须低延迟,查缓存(如
redis.HGet("user:123", "notify_preference"))可以,但要设默认兜底 - 注意空值处理:用户没填偏好时,按渠道可用性降级,比如微信不可用就切短信,别直接 panic
如何让路由支持灰度和 AB 测试
灰度不是靠改代码,而是靠运行时参数干预。关键是在路由入口加一层 RouterContext,里面带 traceID、version、abGroup 字段,再结合配置中心(如 Nacos、Consul)动态拉取当前灰度比例。
典型错误是把灰度逻辑写死在策略里,导致每次上线都要发版才能调比例。
- 用
rand.Float64() 控制是否走新渠道,而不是 if version == "v2" - AB 分组建议用
xxhash.Sum64String(userID + traceID)取模,保证同一用户稳定落在同一组 - 务必记录路由决策日志,字段至少含:
event_id、chosen_channel、reason(如"ab_group_2"或"fallback_to_sms")
微信模板消息和短信内容怎么统一组装又不耦合
不能让路由层拼消息体,那会把渠道细节泄漏上去。正确做法是定义抽象的 MessagePayload 结构体,只含业务字段(如 OrderID、Amount),再由各渠道的 Renderer 实现去转成具体格式。
常见坑是模板 ID 写死在业务代码里,结果微信模板被驳回后全量失败。
- 微信渲染器从配置中心读
template_id_map[scene],短信渲染器读sms_sign_map[scene] -
Renderer.Render()方法应返回(string, error),错误要明确区分:模板缺失、变量缺失、长度超限 - 对敏感字段(如手机号)做脱敏再传给渲染器,路由层不碰原始内容
channel 不可用时怎么自动降级且不丢消息
降级不是简单换一个 switch 分支,而是要有状态感知和异步兜底。微信接口 503 或短信网关超时,不能当场返回失败,得记日志 + 发到延迟队列重试。
很多人忽略的是:降级路径本身也可能失败,比如短信也挂了,这时必须有最终一致性保障。
- 用
context.WithTimeout(ctx, 800*time.Millisecond)控制单次调用,超时即触发降级 - 降级前先写入本地
sqlite或 Redis 的失败队列(key 为"failed_notify:<event_id>"</event_id>),带上原始 payload 和尝试次数 - 单独起 goroutine 轮询失败队列,按指数退避重试(1s → 3s → 9s),超过 3 次写入告警表并通知运维
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











