场景设计专项:营销短信推送系统设计
营销短信推送系统业务定位与整体设计框架
核心知识点
- 项目业务定位:面向 B 端商户提供短信营销服务,支持即时批量推送、定时人群推送,支撑单日千万条短信下发。
- 系统完整设计分层框架:需求分析 → 业务模块分层 → 技术架构选型 → 核心推送流程 → 高并发 / 幂等 / 容错专项设计 → 数据存储方案 → 监控运维体系 → 系统扩容演进。
- 系统设计核心目标:高并发承载、消息不丢失、无重复短信、多通道故障自动切换、全链路数据可追溯。
生活化举例
可以把这套短信系统理解为一家大型短信代发服务商:
线下各类门店(商户)可以来后台创建营销活动,既能立刻给客户发短信,也能设定固定时间自动发送;同时设置发送上限防止骚扰客户,多家短信运营商备用,某一家服务商故障自动切换,每条发送记录完整留存方便核对。
整体框架流程图
系统需求拆解(功能需求 + 非功能需求)
核心知识点
- 系统需求分为两大类别:功能性需求(系统能做什么业务操作)、非功能性需求(系统运行质量标准);
- 功能性需求围绕商户、人群、活动、推送、通道、日志、运营看板七大业务域划分;
- 非功能性需求定义并发、可用性、延迟、一致性、扩展性、可观测六大运行约束。
生活化举例
以短信代发门店举例:
功能需求 = 门店能提供的全部服务:商家入驻、筛选客户、定时发活动短信、多家短信渠道备用、查询发送记录;
非功能需求 = 门店服务标准:高峰期一次性处理百万条短信、渠道坏了不影响发消息、客户操作页面响应快、所有发送记录不会丢失、后续可以新增短信服务商、出问题能快速查到原因。
需求分类明细表格
表 1 功能性需求清单
| 业务模块 | 包含功能 |
|---|---|
| 商户管理 | 商户入驻、短信额度配置、第三方通道密钥加密存储 |
| 人群管理 | 客户标签管理、多条件人群筛选、黑名单过滤 |
| 活动管理 | 创建即时活动、创建定时活动、绑定短信模板 |
| 推送能力 | 手动即时批量下发、定时自动批量下发 |
| 通道管理 | 多服务商通道接入、主通道故障自动切换备用通道 |
| 流量防护 | 商户总额度限制、单手机号发送频次限制、IP 访问限制 |
| 消息容错 | 消息自动重试、死信兜底补发、失败号码人工补发 |
| 日志追溯 | 按手机号 / 活动 / 时间查询完整发送记录 |
| 运营看板 | 推送总量、成功率、失败率、各通道数据统计展示 |
表 2 非功能性需求清单
| 性能维度 | 约束标准 |
|---|---|
| 高并发 | 单日支撑千万条短信下发,瞬时可承载百万条消息流量 |
| 高可用 | 单通道、单服务节点故障,整体推送业务不中断 |
| 低延迟 | 批量任务分发速度快,接口响应控制在 100ms 以内 |
| 数据一致 | 定时任务、消息消费保证消息不重复、不丢失 |
| 可扩展 | 新增短信服务商通道无需修改核心业务代码 |
| 可观测 | 全链路日志留存,异常自动告警,故障可快速定位 |
五层业务代码分层架构设计
核心知识点
- 采用标准后端五层分层架构:控制层、业务层、工具层、中间件封装层、存储层,职责单一、代码解耦;
- 每层只处理自身职责范围内逻辑,禁止跨层直接调用,便于后期维护、迭代、单元测试;
- 中间件统一封装层是项目扩展关键点,后续更换 Redis、MQ 等组件仅改动封装层,不侵入业务代码。
生活化举例
类比快递网点分工:
- 前台接待(控制层):只负责接待客户、核对信息、收寄快递,不处理分拣运输;
- 分拣班组(业务层):根据目的地、快递类型做分拣、安排配送路线,核心业务处理;
- 通用工具组(工具层):称重设备、打印面单机器、信息脱敏工具,全网点通用;
- 物流合作商对接组(中间件封装层):统一对接多家运输公司,对外只提供一套标准发货接口;
- 仓库台账组(存储层):只负责录入、查询快递入库出库记录,不参与分拣。
分层职责明细表格
| 分层名称 | 核心职责 | 内部包含模块 |
|---|---|---|
| 控制层 Controller | 接收前端请求,参数校验、鉴权、统一返回封装、全局异常捕获 | 商户接口、活动接口、定时任务配置接口、推送触发接口、数据看板接口、通道配置接口 |
| 业务层 Service | 实现全部核心业务逻辑,业务规则判断、数据组装、多组件协同调用 | 商户服务、人群筛选服务、活动调度服务、消息推送服务、统计看板服务 |
| 工具层 Util | 通用静态工具,无业务耦合,全项目复用 | JWT 鉴权、密码加密、手机号脱敏、全局 MsgId 生成、Excel 导入导出、Lua 脚本工具、文件上传工具 |
| 中间件封装层 | 统一封装各类中间件操作,对外提供标准工具方法 | Nacos 配置工具、Redis 缓存 / 锁工具、RabbitMQ 消息工具、Sentinel 限流熔断工具、ES 日志读写工具 |
| 存储层 Mapper | 仅负责数据库、对象存储的数据 CRUD,无业务逻辑 | MySQL 表操作、ES 日志操作、MinIO 素材文件操作 |
分层调用流程图
整体分布式技术架构选型
核心知识点
- 整体技术栈分为五大板块:基础开发框架、微服务治理、缓存体系、消息队列、调度 / 存储 / 监控运维;
- 每个中间件对应解决系统特定问题,选型完全匹配前文功能、非功能需求;
- 采用微服务分布式架构,支持水平扩容、多组件协同完成千万级短信推送能力。
生活化举例
类比大型物流中心整套配套设施:
- 基础框架 = 园区通用办公系统;
- Nacos = 园区总调度台,统一登记所有网点、同步配送规则;
- Sentinel = 园区安检闸机,限制货物流量、异常线路临时封闭;
- 二级缓存 = 园区临时周转货架,减少仓库反复调取;
- RabbitMQ = 货物中转分拣流水线,削峰缓冲大批量货物;
- Quartz = 定时配送班车,定点发车;
- MySQL+ES = 纸质台账 + 电子档案库,冷热数据分开存放;
- Docker、ELK = 标准化货车、全程监控摄像头。
完整技术栈明细表格
| 技术分类 | 组件 | 解决的业务问题 |
|---|---|---|
| 基础开发框架 | SpringBoot、SpringCloud、MyBatis、QLExpress、Quartz | 项目基础开发、数据库操作、人群筛选规则解析、定时任务执行 |
| 微服务治理 | Nacos、Sentinel、Seata (可选) | 注册中心、动态配置热更新、限流熔断、分布式事务 |
| 缓存体系 | Caffeine 本地缓存 + Redis 分布式缓存 | 减轻 DB 压力、分布式锁、幂等标记、限流、过滤无效手机号 |
| 消息队列 | RabbitMQ | 异步削峰、消息重试、死信兜底,避免高并发压垮服务 |
| 分层存储 | MySQL、Elasticsearch、MinIO | 热业务数据、海量明细日志、批量人群文件 / 素材存储 |
| 监控运维 | ELK、SkyWalking、Docker Compose | 全链路日志、链路追踪、本地标准化开发环境 |
分布式架构分层流程图
缓存体系设计(Caffeine+Redis 二级缓存)
核心知识点
- 二级缓存分层逻辑:进程内本地缓存 Caffeine 作为一级缓存,Redis 分布式缓存作为二级兜底缓存;
- Caffeine 优势:纯内存操作、无网络 IO,读写性能远高于 Redis,采用 LRU 淘汰策略;
- Redis 承担分布式场景能力:分布式锁、布隆过滤器、滑动窗口限流、幂等标记、额度计数器;
- 配套缓存优化方案:布隆过滤器防穿透、分布式锁防击穿、过期时间随机偏移防雪崩。
生活化举例
线下便利店双层储物区
- 收银台手边小货架(Caffeine 本地缓存):热销商品,随手可取,不用去仓库,速度极快;
- 门店后方大仓库(Redis):存放全部商品,全门店所有收银台共用;
- 门口黑名单告示(布隆过滤器):顾客要不存在的商品,直接拒绝,不用翻仓库;
- 限量爆款限购锁(分布式锁):同一时间只允许一人调取库存,防止超卖击穿仓库;
- 商品保质期错开(随机过期时间):不会所有商品同一天过期,仓库瞬间查询拥堵。
二级缓存工作流程
Redis 各类业务用途对照表
| Redis 功能模块 | 业务场景 | 作用说明 |
|---|---|---|
| 分布式锁 | Quartz 定时任务集群调度 | 保证同一定时任务仅单个节点执行,避免重复生成短信 |
| 布隆过滤器 | 手机号校验 | 提前过滤黑名单、无效空号,减少 MySQL 无效查询 |
| Lua 滑动窗口限流 | 流量防护 | 控制单手机号、商户、IP 每日短信发送上限,防刷防骚扰 |
| MsgId 幂等标记 | MQ 消息消费 | 记录已下发短信唯一标识,避免重复推送同一营销短信 |
| 额度计数器 | 商户管理 | 统计商户当日已发送短信数量,到达阈值停止下发 |
| 会话存储 | 商户后台登录 | 存储商户登录 Token,实现登录态维持 |
RabbitMQ 消息队列设计(异步削峰 + 重试 + 死信)
核心知识点
- 引入 RabbitMQ 核心目的:同步下发转异步处理,实现流量削峰填谷,避免批量活动压垮服务线程池;
- 队列分层设计:业务正常推送队列 + 死信重试队列两套队列隔离;
- 消息可靠性三重保障:生产者确认、消息持久化、消费者手动 ACK;
- 重试机制分级:消费本地最多 5 次重试,多次失败转入死信队列,死信任务定时 3 轮兜底重试;
- 全局唯一 MsgId 作为幂等标识,所有消息携带该标识,杜绝重复下发。
生活化举例
快递中转站分拣流水线
- 前台下单窗口(业务接口):客户一次性寄上千件快递,不会当场分拣;
- 主分拣流水线(业务队列):快递统一堆放,分拣员匀速处理,不会瞬间拥堵;
- 派送失败包裹存放区(死信队列):地址错误、电话打不通的包裹单独存放,不占用主线;
- 派送规则:同一包裹最多上门派送 5 次,5 次没人签收放到失败存放区;每晚统一再试 3 轮联系收件人;
- 快递单号(MsgId):每件快递唯一编号,避免重复派送同一包裹。
消息完整流转流程图
RabbitMQ 功能场景对照表
| 队列类型 | 使用场景 | 设计作用 |
|---|---|---|
| 业务推送队列 | 正常待下发短信消息承载 | 异步削峰,平缓处理批量营销活动流量 |
| 死信重试队列 | 本地 5 次下发失败消息存储 | 不阻塞主线业务,统一兜底重试 |
| 可靠性机制 | 实现方式 | 解决问题 |
|---|---|---|
| 生产者确认 confirm | 投递消息后等待 MQ 返回 ACK | 防止消息投递中途丢失 |
| 消息持久化 | 队列、消息均开启持久化存储 | MQ 服务宕机,消息不会清空 |
| 消费者手动 ACK | 下发成功后再确认删除消息 | 消费过程服务崩溃,消息自动重回队列 |
分布式定时调度方案(Quartz 持久化任务 + Redis 分布式锁)
核心知识点
- SpringTask 原生缺陷:内存级任务、集群多节点会重复执行、服务重启任务丢失、无法可视化管理;
- Quartz 核心能力:任务持久化到 MySQL、支持动态增删改任务、多维度定时规则配置;
- Redis 分布式锁作用:集群环境下保证同一个定时任务同一时间仅单个节点执行;
- 锁超时 TTL 机制:防止服务宕机导致死锁,保障调度持续可用;
- 与业务联动:定时任务执行完成后批量生成短信消息投递 RabbitMQ。
生活化举例
连锁门店统一定时大扫除计划
- 旧方案(SpringTask):每家分店单独设置闹钟,到点所有分店同时打扫同一批客户活动数据,重复劳动,门店关机后打扫计划直接消失;
- 新方案(Quartz 台账):所有打扫计划统一登记在总台账(MySQL 持久化),店长后台随时修改打扫时间、新增计划;
- 分布式锁(专属钥匙):打扫前必须领取唯一钥匙,拿到钥匙的分店执行人群筛选生成短信,其余分店直接跳过;
- 钥匙过期机制:分店打扫中途断电关门,钥匙超时自动归还,不会锁住任务导致当天不执行。
定时任务完整流转流程图
方案对比表格
| 方案 | 集群重复执行 | 任务丢失 | 动态修改任务 |
|---|---|---|---|
| 原生 SpringTask | 会重复执行 | 服务重启丢失 | 必须重启服务生效 |
| Quartz + Redis 分布式锁 | 完全杜绝重复执行 | MySQL 持久化永不丢失 | 后台实时修改,无需重启服务 |
Sentinel 限流熔断 + 多短信通道故障切换设计
核心知识点
- Sentinel 两大核心能力:流量限流、服务熔断降级;
- 三层限流维度:单手机号发送频次、商户每日短信总额度、客户端 IP 访问限流;
- 熔断机制逻辑:统计第三方短信通道错误率、超时率,达到阈值自动熔断隔离;
- 多通道路由策略:Nacos 配置维护多服务商通道权重、优先级,通道熔断后自动切换备用线路;
- 半开探测:熔断冷却周期结束后,少量流量试探通道,恢复正常则重新启用。
生活化举例
外卖多配送服务商调度
- 限流规则:单个顾客一天最多收 5 条营销短信、单商家每日有固定配送上限、恶意高频访问 IP 限制下单,避免资源被占用;
- 通道熔断:某配送团队大量订单超时、丢单,系统暂时不再派单给该团队;
- 多备用渠道:同时对接多家配送商,主渠道故障自动分流订单给其他团队;
- 半开探测:暂停派单一段时间后,少量订单测试该配送商是否恢复运力,正常后恢复使用。
流量校验与通道路由流程图
方案对比表
| 方案 | 存在问题 | 优化后效果 |
|---|---|---|
| 无 Sentinel + 单通道 | 爬虫刷接口、单通道故障全体业务阻塞 | 三层限流拦截恶意流量,通道故障自动切换 |
| Sentinel + 多通道 | 无备用线路,熔断后业务中断 | 多服务商通道无感切换,不中断推送 |
冷热分层存储设计 MySQL + Elasticsearch
核心知识点
- 冷热数据划分标准 热数据:业务高频查询、需要实时更新的简短状态数据; 冷数据:海量完整明细日志,检索频次低、数据量大,无需频繁更新。
- MySQL 只承载热业务数据,避免大表海量日志拖垮数据库 IO;
- Elasticsearch 专门存储短信全量下发明细,依靠倒排索引实现多条件快速检索;
- 采用独立日志 MQ 异步批量写入 ES,和短信下发主业务完全解耦,不阻塞推送流程;
- ES 配置索引生命周期管理,按天分索引,自动清理过期日志,控制磁盘占用。
生活化举例
商铺记账分层存档
- 前台小账本(MySQL 热数据):只记录订单号、手机号、发送结果等简短信息,日常快速查询是否发送成功;
- 仓库档案柜(ES 冷数据):存放每条短信完整回执、错误码、调用耗时等详细记录;档案按日期分盒子存放,超过 7 天的档案自动清理;
- 专职归档员(日志 MQ):店铺营业结束后统一整理单据存入档案柜,不影响前台接待顾客。
数据写入与查询流转流程图
存储分工对照表
| 存储组件 | 存储内容 | 适用场景 | 核心优势 |
|---|---|---|---|
| MySQL | 商户、活动、人群、短信精简推送记录、黑名单 | 日常业务状态查询、商户额度统计、活动管理 | 支持事务、稳定可靠,适合高频更新短字段数据 |
| Elasticsearch | 每条短信完整下发明细、渠道回执、报错详情 | 故障排查、批量明细导出、多维度模糊检索 | 海量数据检索毫秒级响应,支持复杂多条件筛选 |
| MinIO | 人群批量导入 Excel、短信营销图片模板 | 文件上传下载、素材存储 | 对象存储,不占用数据库磁盘,支持大文件 |
优化前后对比
| 优化前(日志全量存 MySQL 单表) | 优化后(冷热分层存储) |
|---|---|
| 单表千万级数据,多条件检索耗时 40s 以上 | 多条件明细检索 20ms 左右 |
| 每日日志新增 12G 磁盘,磁盘持续告警 | MySQL 磁盘占用减少 90% |
| 日志同步写入主业务链路,瞬间打满数据库 IO | 日志异步写入 ES,完全不影响短信下发性能 |
| 无法自动清理历史数据,需手动删表 | ES 索引生命周期自动清理过期日志 |
Nacos 配置中心热更新设计
核心知识点
- Nacos 两大核心能力:注册中心、配置中心,本模块聚焦配置管理能力;
- 统一托管全业务可变配置:短信通道信息、限流阈值、推送额度、重试次数、ES 索引过期时间等;
- SpringBoot
@RefreshScope注解实现 Bean 动态刷新,修改配置无需重启服务; - Namespace 环境隔离:dev 开发、test 测试、prod 生产三套环境配置完全隔离,互不干扰;
- 敏感配置加密存储:短信通道 API 密钥加密存放,避免明文泄露风险。
生活化举例
连锁奶茶店统一价目后台
- 所有门店统一线上电子价目表(Nacos 配置),包含单品价格、每日限购数量、供应商联系方式;
- 总部后台修改价格、限购规则,所有门店收银设备实时同步生效,不用每家门店重启机器;
- 门店区分测试样板间、正式营业区(Namespace),测试修改价格不会影响线上顾客;
- 供应商对接密码加密保存,门店员工看不到原始密钥。
配置托管内容清单表
| 配置分类 | 存放内容 |
|---|---|
| 短信通道配置 | 通道地址、加密密钥、权重、熔断阈值、备用通道列表 |
| 流量限流配置 | 单手机号日发送上限、商户总额度、IP 限流阈值 |
| 消息重试配置 | 本地最大重试次数、死信每日兜底轮次 |
| 存储运维配置 | ES 日志自动清理天数、缓存随机过期偏移时长 |
优化前后对比
| 改造前(硬编码 / 本地 yml 配置) | 改造后(Nacos 动态配置) |
|---|---|
| 修改参数需要重新打包、重启服务,耗时 30 分钟左右 | 控制台一键发布,1 秒全服务生效,无需停机 |
| 开发 / 测试 / 生产共用一份配置,容易误改线上参数 | Namespace 隔离三套环境,配置完全独立 |
| 密钥明文写在配置文件,上传代码仓库存在泄露风险 | Nacos 支持配置加密,密钥不透明文 |
| 多服务实例需要逐个修改本地配置,维护成本高 | 一处修改,所有集群实例同步更新 |
JVM 堆内存参数调优方案
核心知识点
- JVM 堆核心参数 Xms、Xmx:Xms 为堆初始内存,Xmx 为堆最大内存;Xms=Xmx 可消除运行时堆扩容带来的 STW 停顿。
- 堆分区划分:Eden 区、Survivor 区、老年代;短期业务对象优先分配 Eden,长期存活对象晋升老年代。
- GC 分类与影响:Minor GC 回收新生代、Full GC 回收整个堆,Full GC 会产生长时间全局暂停,直接造成接口卡顿。
- 配套排查能力:开启 GC 日志持久化、OOM 自动 dump 堆快照,用于离线分析内存泄漏、频繁 GC 问题。
- 监控老年代内存水位,提前发现内存持续上涨隐患,避免服务卡死宕机。
生活化举例
办公储物间规划
- Xms=Xmx:储物间一开始就给到固定最大面积,不用中途扩建,扩建时全员停工等待的卡顿现象消失;
- Eden 区:临时快递、短期单据存放区,占储物间 1/3 空间,频繁清理;
- 老年代:长期存档文件存放区,清理频率很低;
- GC 日志 + OOM dump:每次打扫全程记录清单,储物间堆满时自动留存全部物品,方便事后排查堆积原因。
内存分配与 GC 流转流程图
调优前后指标对比表
| 指标维度 | 调优前(Xms 远小于 Xmx,无日志) | 调优后(固定堆 + 新生代配比 + 日志 dump) |
|---|---|---|
| 日均 Full GC 次数 | 15 次 | 0~1 次 |
| GC 总停顿时长 | 高,接口频繁随机卡顿 | 停顿时长下降 92% |
| 堆扩容 STW 停顿 | 持续发生 | 完全消除 |
| 内存故障排查 | 无日志,难以定位 | GC 日志 + 堆快照快速定位泄漏点 |
常见线上痛点
- Xms < Xmx:业务流量上涨时 JVM 反复扩容堆内存,每次扩容触发 STW,接口出现周期性延迟;
- 新生代内存过小:Eden 快速填满,Minor GC 频繁,持续占用 CPU,影响消息消费速度;
- 未开启 GC 日志、dump 文件:发生 OOM、长时间 Full GC 时无任何排查依据;
- 存在内存泄漏:老年代内存持续上涨无人预警,最终服务卡死宕机。
落地调优方案
- 统一配置 Xms = Xmx,固定堆内存,杜绝运行期堆扩容;
- 新生代设置为堆总内存 1/3,提升短期消息对象容纳量,减少 Minor GC 频率;
- 启动参数开启持久化 GC 日志,记录每次 GC 耗时、回收内存大小、停顿时间;
- 配置 OOM 触发时自动 dump 堆快照文件,留存现场用于离线分析;
- 接入监控面板,持续观测老年代内存增长曲线,设置水位告警。
Docker Compose 容器化标准化环境
核心知识点
- Docker 镜像作用:将项目代码、运行依赖打包成统一镜像,环境与代码绑定,保证运行环境一致。
- Docker Compose 能力:通过 yaml 文件一键编排 MySQL、Redis、RabbitMQ 等全套中间件,一条命令拉起完整开发环境。
- 环境标准化价值:开发、测试、预发、生产使用相同镜像与中间件版本,消除 “本地正常线上报错” 兼容问题。
- 轻量化部署:新人无需手动下载、安装、配置各类中间件,降低环境搭建成本。
- 环境可复用:配置文件提交代码仓库,团队所有人共用一套环境脚本。
生活化举例
连锁门店标准化后厨套装 改造前:每个厨师单独采购烤箱、冷藏柜,版本新旧不一,做出来成品有差异;新人入职花 4 小时逐个安装调试设备。 改造后:总部提供成套标准化设备集装箱:
- 集装箱内置烤箱、冷藏柜、操作台(对应业务镜像 + 全套中间件容器);
- 开箱即用,10 分钟全部设备启动完成;
- 全国所有分店设备型号完全相同,出品标准统一,不会出现奇怪故障。
环境搭建流程对比流程图
两种搭建方式对比表格
| 对比维度 | 传统手动搭建环境 | Docker Compose 容器化方案 |
|---|---|---|
| 新人搭建耗时 | 4 小时左右 | 10 分钟 |
| 中间件版本差异 | 开发、测试环境版本混乱 | 全环境统一固定版本 |
| 重复配置工作量 | 每位开发重复安装配置 | 一份脚本全团队复用 |
| 环境兼容 Bug | 每月频繁出现 | 全年无版本兼容故障 |
| 环境迁移成本 | 换电脑需全部重装 | 复制 yaml 文件即可一键重建 |
落地实现方案
- 编写项目 Dockerfile,打包 SpringBoot 业务服务为镜像;
- 编写 docker-compose.yml,统一定义 MySQL、Redis、RabbitMQ 容器参数、端口、持久化挂载目录;
- 锁定所有中间件固定版本,禁止本地随意升级;
- 提供启动、停止、清理脚本,简化操作;
- 测试、预发环境复用相同镜像部署,保证线上线下环境无差异。
系统完整核心推送全链路流程(定时营销活动主线)
核心知识点
- 整合前面所有组件:Quartz 定时任务、Redis 分布式锁、QLExpress 人群筛选、MsgId 全局唯一标识、RabbitMQ 异步队列、Sentinel 限流熔断、多短信通道、冷热分层存储、幂等校验、死信兜底重试整套链路串联;
- 区分两大推送分支:即时短信推送、定时营销短信推送,定时活动是系统流量最大的场景;
- 全链路每一步都配套容错、幂等、性能优化方案,不存在单点短板;
- 全链路埋点链路追踪,所有操作生成唯一 TraceId,日志统一归集便于问题排查。
生活化举例
商超定时营销短信完整流程
- 运营提前配置好周末促销活动、目标客户群体、发送时间(创建活动入库);
- 到预定时间,所有分店调度员同时收到提醒,只有抢到专用钥匙的调度员才处理客户名单(分布式锁);
- 筛选有效会员,过滤黑名单客户(布隆过滤器);
- 给每一位客户生成唯一活动编号 MsgId;
- 批量把待发送单据送入分拣流水线 RabbitMQ,前台不用当场处理;
- 分拣员拿单据前先查登记本,已经发送过的客户直接跳过(幂等);
- 限制单个客户、单商户每日接收短信数量(三层限流);
- 优先联系合作运营商发送,运营商故障自动切换备用渠道;
- 发送成功简单记录台账 MySQL,完整通话回执存入档案库 ES;
- 发送失败最多重试 5 次,依旧失败单独存放,夜间统一再次重试 3 轮;最终失败人工补发。
全链路完整流程图
链路各环节对应技术方案汇总表
| 流程环节 | 使用组件 | 解决的核心问题 |
|---|---|---|
| 定时活动触发 | Quartz + Redis 分布式锁 | 集群重复生成短信、任务丢失 |
| 手机号过滤 | 布隆过滤器、QLExpress 规则引擎 | 无效号码穿透数据库、精准人群筛选 |
| 消息投递削峰 | RabbitMQ 业务队列、消息持久化、生产者 ACK | 高并发压垮服务、消息丢失 |
| 重复下发拦截 | Redis MsgId 幂等校验 | 同一用户收到多条相同营销短信 |
| 流量管控 | Redis Lua 三层限流 | 商户超限、恶意刷短信消耗额度 |
| 通道容错切换 | Sentinel 熔断 + 多服务商通道 | 单通道故障导致全部推送阻塞 |
| 数据分层存储 | MySQL 热记录 + ES 明细日志 | 大表查询缓慢、磁盘占用过高 |
| 失败兜底 | 本地 5 次重试 + 死信 3 轮补发 | 网络波动、通道临时故障导致短信丢失 |
| 底层基础保障 | Nacos、Docker、JVM 调优 | 配置修改重启、环境不一致、GC 卡顿 |
MySQL 核心业务数据表结构设计
核心知识点
- 分库分表策略:当前业务量级单库单表可支撑,暂不做分库分表;仅推送简表随业务增长可按月分表缓解数据压力。
- 冷热数据分离设计:MySQL 仅保存业务热数据,完整明细日志不存入 MySQL,交给 ES 存储。
- 表设计规范:主键自增 / 雪花 ID、状态字段统一枚举、创建 / 更新时间、逻辑删除标识,便于业务统计与软删除。
- 关联关系:商户一对多活动、活动一对多推送记录、商户一对多短信通道。
生活化举例
门店台账分类登记
- 商户台账(merchant 表):记录合作商家基础信息、每月短信发送额度;
- 渠道合作台账(sms_channel 表):登记所有短信运营商对接地址、密钥、优先级;
- 营销活动登记本(sms_activity 表):商家创建的每一场营销活动、下发时间、筛选人群;
- 客户发送简记台账(sms_record 表):仅简单记录哪个号码、哪场活动、发送成功与否,详细回执单独存档;
- 黑名单记录本(black_list 表):不愿接收营销短信的客户手机号,每次筛选自动过滤。
核心数据表说明表
| 表名 | 核心作用 | 核心关键字段说明 |
|---|---|---|
| merchant 商户表 | 存储入驻商户基础信息、短信额度 | merchant_id (主键)、商户名称、daily_limit 日发送额度、channel_secret 加密渠道密钥、status 商户启用状态、create_time |
| sms_channel 短信通道表 | 存储第三方短信服务商对接配置 | channel_id、channel_name、api 地址、密钥、weight 权重、circuit_breaker_threshold 熔断阈值、enable 状态 |
| sms_activity 营销活动表 | 存储即时 / 定时营销活动配置 | activity_id、merchant_id、crowd_id 人群 ID、template 短信模板、send_time 定时下发时间、activity_status 活动状态、is_timed 是否定时活动 |
| crowd 人群表 | 存储商户自定义筛选人群规则 | crowd_id、merchant_id、rule_content QLExpress 筛选规则、crowd_name 人群名称 |
| sms_record 短信推送简表 | 存储每条短信精简下发状态(热数据) | msg_id 唯一主键、phone 手机号、activity_id、channel_id、send_status 下发状态、send_time 发送时间,无详细回执内容 |
| black_list 黑名单表 | 存储拒绝营销短信的手机号 | id、phone、black_type 拉黑类型、expire_time 拉黑失效时间 |
关键设计规范
- 逻辑删除:所有业务表统一使用 is_deleted 字段,不物理删除数据,方便数据对账与恢复;
- 时间字段:每张表统一 create_time、update_time,自动填充用于统计、排查;
- 状态枚举:活动状态、发送状态、商户状态使用数字枚举,减少字符串存储开销;
- 索引设计:
- sms_record:msg_id 唯一索引、phone 普通索引、activity_id 联合索引,满足查询状态;
- sms_activity:merchant_id 索引,快速查询商户名下所有活动;
- black_list:phone 唯一索引,人群筛选快速匹配黑名单。
系统监控、告警与运维配套方案
核心知识点
- 系统分为业务指标、中间件指标、服务 JVM 指标三类监控维度,覆盖业务、中间件、应用三层;
- 全链路观测体系:ELK 收集日志、SkyWalking 实现分布式链路追踪,快速定位异常请求;
- 告警通道统一接入钉钉,配置多阶梯告警规则,区分普通预警与严重故障;
- 内置自动化运维能力,减少人工干预,包含配置动态更新、日志自动清理、失败短信人工补发等功能。
生活化举例
大型商超运营监控中心
- 营业数据看板(业务监控指标):当日营销短信发送总量、成功率,直观判断活动效果;
- 设备监控面板(中间件 / JVM 指标):流水线堆积货物数量、仓库存储空间、设备清扫频率(GC);
- 故障报警喇叭(钉钉告警):发送成功率过低、流水线堵塞、设备频繁故障自动推送消息给运维人员;
- 自动化管理工具:价目表线上修改不用停机、过期单据自动清理、失败订单后台一键补发。
监控指标分类明细表格
1. 业务监控指标
| 指标名称 | 监控意义 | 告警阈值参考 |
|---|---|---|
| 短信发送总量 / 成功率 | 判断营销活动是否正常下发 | 成功率低于 90% 触发告警 |
| 各通道发送占比 | 监控通道负载均衡、单通道故障 | 某通道流量突降 50% 预警 |
| 失败短信数量 | 识别批量下发异常 | 每分钟失败量超 200 条预警 |
2. 中间件监控指标
| 组件 | 监控指标 | 告警阈值参考 |
|---|---|---|
| RabbitMQ | 消息堆积数量、消费速率、队列长度 | 堆积超过 5000 条触发告警 |
| Redis | CPU 使用率、内存占用、连接数 | CPU 持续高于 80% 预警 |
| MySQL | 慢查询、连接数、磁盘使用率 | 磁盘占用 90% 预警 |
| Elasticsearch | 索引存储、分片健康状态 | 分片异常、磁盘爆满告警 |
3. 应用服务 JVM 指标
| 指标名称 | 监控意义 | 告警阈值参考 |
|---|---|---|
| Full GC 频次 | 判断内存是否存在泄漏、堆分配不合理 | 单日 Full GC 超过 5 次预警 |
| 堆内存使用率 | 监控内存水位,提前预防 OOM | 堆内存持续 90% 占用告警 |
| 接口 QPS、平均响应时间 | 识别接口卡顿、流量突增 | 接口响应超 100ms 持续告警 |
全链路观测流程
自动化运维能力清单
- Nacos 动态配置:通道参数、限流阈值线上修改,无需重启服务;
- ES 索引生命周期管理:7 天自动清理过期明细日志,控制磁盘容量;
- 失败消息管理后台:支持按活动、手机号批量导出失败号码、手动补发;
- Docker Compose 一键启停全套开发环境,标准化本地调试;
- 日志分级存储:ERROR 级日志重点检索,INFO 日志短期留存。
系统扩容与长期演进规划
核心知识点
- 按照业务增长分为三个阶段:短期扩容、中期微服务拆分、长期异地多活架构;
- 短期扩容不改动代码,仅横向扩容实例、中间件分片,快速支撑流量上涨;
- 中期基于业务域拆分微服务,解除模块耦合,各业务独立扩容迭代;
- 长期多机房异地部署,实现机房级故障容灾,支撑超大规模商户体量;
- 每阶段配套对应的中间件、存储同步扩容改造方案。
生活化举例
快递网点扩张规划
- 短期旺季扩容:分拣流水线加派人手、新增周转货架,不用改造门店结构;
- 中期业务拆分:把收件、分拣、派送、客户售后拆成独立片区,互不干扰;
- 长期多地分中心:省内多个城市建立分拣总仓,一处仓库停工,其他仓库承接业务,不影响整体配送。
分阶段扩容方案表格
阶段 1:短期快速扩容(单日千万短信,流量临时暴涨)
| 扩容对象 | 改造方案 | 作用 |
|---|---|---|
| RabbitMQ 消费服务 | 新增消费实例节点,线性提升消息处理速度 | 缓解消息堆积,提升下发吞吐量 |
| Redis | 增加 Redis 分片,拆分缓存 key,分摊 CPU 与内存压力 | 避免单节点内存爆满、CPU 打满 |
| 服务实例 | 横向复制推送、活动服务实例,Nacos 自动注册负载均衡 | 分摊接口与消费请求压力 |
| 通道资源 | Nacos 新增第三方短信通道配置,分流单通道流量 | 防止单通道过载、触发运营商限流 |
阶段 2:中期微服务拆分(商户量持续增长,模块耦合严重)
| 拆分方向 | 拆分内容 | 收益 |
|---|---|---|
| 商户管理服务 | 独立商户信息、额度、渠道配置相关逻辑 | 商户相关操作独立扩容,不占用推送资源 |
| 活动调度服务 | 独立人群筛选、定时任务调度模块 | 营销批量计算不影响短信下发消费 |
| 消息推送服务 | 单独承载 MQ 消费、通道下发核心逻辑 | 推送能力可无限独立扩容 |
| 统计看板服务 | 单独处理数据聚合、报表计算 | 报表查询不占用核心下发数据库 IO |
阶段 3:长期异地多活架构(超大商户体量,机房容灾需求)
- 多机房独立部署整套服务集群,Nacos 跨机房注册发现;
- 短信通道按机房隔离分配流量,单机房故障流量切至备用机房;
- MySQL 主从同步跨机房数据,ES 集群多机房分片部署;
- 关键定时任务多机房冗余调度,保证极端故障不丢失推送任务。
扩容演进流程图
营销短信推送系统整体知识总结
核心知识点
- 整套系统完整设计链路:需求定义 → 五层代码分层 → 分布式技术栈选型 → 各中间件专项设计 → 全业务推送主流程 → 四大稳定性专项方案 → 数据库表设计 → 监控运维 → 分阶段扩容演进;
- 所有中间件各司其职,互相配合解决高并发、重复消息、消息丢失、服务故障四大线上核心痛点;
- 整套架构设计思想:异步解耦、分层隔离、冷热分离、多级兜底、可观测、平滑扩容。
生活化整体类比
整套系统类比大型商超短信营销服务中心:
- 需求:商家可以创建即时 / 定时营销短信,限制发送额度,多供应商备用,发送记录可查询;
- 分层分工:前台接待、业务分拣、通用工具、第三方渠道对接、台账登记,每层职责独立;
- 配套设施:临时货架(二级缓存)、分拣流水线(RabbitMQ)、定时配送班组(Quartz)、安检限流闸机(Sentinel)、线上统一调价后台(Nacos);
- 完整流程:定时活动生成客户名单 → 过滤无效客户 → 流水线分批发送 → 限流校验 → 多渠道分发 → 失败包裹单独重试;
- 兜底保障:多层防重复机制、多级消息重试、故障渠道自动切换;
- 数据存储:简易台账 MySQL、详细档案 ES;
- 运维监控:全流程监控大屏,异常自动报警;
- 扩张规划:短期加人手、中期拆分业务片区、长期多地分中心容灾。
全模块技术作用汇总表
| 模块名称 | 核心解决问题 |
|---|---|
| 五层业务分层架构 | 代码解耦、职责单一,便于迭代维护 |
| Caffeine+Redis 二级缓存 | 降低 DB、中间件压力,防穿透 / 击穿 / 雪崩 |
| RabbitMQ 异步队列 | 高并发削峰,消息分级重试、死信兜底防丢失 |
| Quartz+Redis 分布式锁 | 集群定时任务不重复执行,任务持久化不丢失 |
| Sentinel 限流熔断 + 多短信通道 | 拦截恶意流量,通道故障自动切换提升可用性 |
| MySQL+ES 冷热分层存储 | 减轻数据库压力,海量明细快速检索 |
| Nacos 配置中心 | 配置热更新,无需重启服务,多环境隔离 |
| JVM 内存调优 | 减少 GC 停顿,避免 OOM,保障消费稳定 |
| Docker Compose | 统一标准化开发环境,消除环境兼容问题 |
| 完整定时推送全链路 | 串联所有组件,实现定时营销完整业务闭环 |
| 四大稳定性专项方案 | 根治并发雪崩、重复短信、通道故障、消息丢失 |
| MySQL 数据表设计 | 规范热数据存储,索引优化查询效率 |
| 监控告警运维体系 | 系统全链路可观测,故障快速感知处理 |
| 分阶段扩容演进方案 | 随业务体量平滑升级架构,避免过度设计 |
核心设计思想梳理
- 异步优先:批量推送全部异步化,不阻塞主线程,抵御瞬时大流量;
- 多层兜底:消息本地重试、死信队列重试、人工补发三级兜底,最大程度避免短信丢失;
- 全链路幂等:从任务生产到消息消费多层拦截,彻底杜绝重复短信;
- 冷热数据隔离:高频短状态存 MySQL,海量明细日志异步存入 ES;
- 故障隔离:通道熔断、服务集群化,单点故障不影响整体业务;
- 可观测性:日志、链路、业务指标全方位监控,异常自动告警;
- 平滑扩容:分短期、中期、长期渐进式升级,架构无需推翻重构。