尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
8月3日每日预警系统
每日预警系统总体设计从业务诉求到架构落地的手记我想分享一下我们最近完成的一个「每日预警系统」——如何把一个看似简单的运营诉求设计成一个可追溯、可演进、性能可靠的工程方案。一、问题定义到底要预警什么业务诉求原始表达记录每天查询到有哪些用户近3天没有交易用户是通过审核的新建表方便查询哪天有哪些不交易的用户。这段话翻译成架构语言实际是三个需求诉求 架构解读连续3天无交易 判定规则需要定义「无交易」的数据口径记录每天方便查询 快照存储按天留存历史可回溯任意一天通过审核的用户 目标人群排除未激活、未认证的噪音我的第一反应 这不能做成「实时查交易记录」而应该做成每日快照。原因有三性能交易表 90 万行每次实时扫描不可接受历史可追溯运营想知道「上周五有哪些人开始沉默」需要留存历史解耦预警计算与实时交易解耦凌晨集中算一次二、数据流设计┌─────────────┐ ┌─────────────────────┐ ┌──────────────┐│ 交易记录 │ │ cn_user_daily_ │ │ cn_user_ ││ buy_record │───▶ │ flow_summary │───▶ │ churn_ ││ 90万行 │ │ 按天聚合 23万行 │ │ warning_ │└─────────────┘ └─────────────────────┘ │ record ││ ▲ └──────┬───────┘│ │定时填充 ││ │(每4分钟凌晨0:02) │└─────────────────┘ ▼┌──────────────┐│ 管理后台页面 ││ 展示最新快照 │└──────────────┘核心决策引入中间聚合层 cn_user_daily_flow_summary为什么不直接用 buy_record买 90 万行原始交易│├─ 问题1JOIN 用 OR 条件(sale_user_idx OR pay_user_idx)→ 索引失效├─ 问题2GROUP BY MAX UNION → 全表扫描└─ 问题3每天查询都重复扫描浪费│▼cn_user_daily_flow_summary按天预先聚合├─ 已经算好每个用户每天的交易数 transaction_count├─ 唯一索引 (stat_date, user_id) → 按天查询走索引└─ 数据量从90万降到23万这就是经典的**「读时计算 → 写时计算」**重构把高频查询的聚合结果提前算好。三、表结构设计预警快照表 cn_user_churn_warning_recordCREATE TABLE cn_user_churn_warning_record (id BIGINT AUTO_INCREMENT PRIMARY KEY,stat_date DATE NOT NULL COMMENT 统计日期,user_id BIGINT NOT NULL COMMENT 用户ID,phone VARCHAR(20),business_name VARCHAR(255),province VARCHAR(50),last_trade_time DATETIME COMMENT 最后交易日,create_time DATETIME DEFAULT CURRENT_TIMESTAMP,UNIQUE KEY uk_date_user (stat_date, user_id),KEY idx_stat_date (stat_date),KEY idx_user_id (user_id));设计要点决策 理由(stat_date, user_id) 唯一索引 同一天同一用户只能一条快照天然防重冗余 phone/business_name/province 反规范化查询免联表数据量小每天几千条冗余成本可忽略last_trade_time 冗余 展示时直接显示无需回查不设 del_flag 快照是历史记录不应删除用 TRUNCATE 做整表重置为什么不存「沉默天数」我一度纠结是否要冗余 silent_days 字段。最终决定不存因为last_trade_time 已经足够推导沉默天数是相对统计日期的如果快照固定存「当时的沉默天数」之后查看语义会混乱相对哪天保持数据最小化宁可前端现算四、核心 SQL连续3天无交易的判定判定逻辑架构师视角「连续3天无交易」有两种实现口径方案A最后交易距今 ≥ 3天MAX(create_time) DATE_SUB(NOW(), INTERVAL 3 DAY)优点一条 SQL简洁缺点是「最后一次交易很久以前」不是严格「连续3个自然日无交易」方案B昨天、前天、大前天这3个自然日都无交易最终采用LEFT JOIN ... s1 ON s1.stat_date 昨天 AND 有交易LEFT JOIN ... s2 ON s2.stat_date 前天 AND 有交易LEFT JOIN ... s3 ON s3.stat_date 大前天 AND 有交易WHERE s1 IS NULL AND s2 IS NULL AND s3 IS NULL优点语义精确符合「昨天前天大前天都没有交易」的原始诉求优点走 uk_stat_date_user_id 唯一索引三个点查极快缺点依赖 daily_flow_summary 的时效性我选择了方案B因为业务原始诉求明确指向「连续3个自然日」。且配合凌晨时序0:02 填昨日数据 → 3:01 统计保证数据就绪。防呆设计INNER JOIN cn_user_daily_flow_summary hist ON hist.transaction_count 0这条 INNER JOIN 确保只预警曾经交易过的用户。否则全平台没交易过的新用户全被捞进来预警就失去意义了。五、定时任务设计每日时间线00:02 fillV2(昨天) → 补齐昨天的 daily_flow_summary03:01 saveChurnWarning() → 跑预警统计写快照依赖时序 预警统计依赖 daily_flow_summary 完整所以必须放在凌晨0:02 填充之后。我特意把预警放到3:01留出近3小时缓冲避免填充任务异常导致预警漏判。幂等性 快照 SQL 用 ON DUPLICATE KEY UPDATE last_trade_time VALUES(last_trade_time)即使任务重复执行或凌晨3:01手动补跑同一天也只会有一条不会产生脏数据。六、接口与页面后端接口接口 作用POST /admin/mall/churnWarning/save 手动触发统计异步POST /admin/mall/churnWarning/list 查询最新快照分页异步化设计 save 接口用线程池异步执行立即返回避免大 SQL 阻塞 HTTP 请求导致超时。// 用项目已有的线程池而非 new Thread()AutowiredQualifier(asyncServiceExecutor)private Executor taskExecutor;PostMapping(/admin/mall/churnWarning/save)public AjaxResult save() {taskExecutor.execute(() - churnWarningService.saveChurnWarning());return AjaxResult.success(统计中稍后刷新);}前端页面手动统计按钮测试/初始化用关键词搜索手机号、企业名沉默天数标签按最后交易日计算绿/橙/红分级分页数据量大时分页展示设计权衡 页面只展示最新一次快照WHERE stat_date (SELECT MAX(stat_date) ...)默认不提供日期选择。因为业务方明确说「不用查历史日期」简化交互。七、架构复盘与改进空间做得对的快照模式把「实时查询」改为「每日归档」历史可回溯聚合中间层引入 daily_flow_summary避免大表反复扫描幂等写入唯一索引 ON DUPLICATE KEY容错重跑反规范化冗余展示字段查询免联表可改进的方向 说明预警通知闭环 目前只记录展示可扩展为企业微信/短信通知滑动窗口 当前是固定「昨天前天大前天」节假日可能误报可改为「最近N天滑动窗口无交易」多维信号 目前只看交易可叠加登录、浏览等行为信号提升准确率沉默天数冗余 如业务需要按沉默天数排序/分组可冗余存 silent_days数据分区 快照表按 stat_date 分区历史数据量大时可归档八、总结这个「每日预警系统」的本质是把业务规则翻译成可执行、可追溯、高性能的工程方案。从架构角度它体现了几条通用原则写时计算优于读时计算 — 聚合结果提前算好快照优于实时 — 历史可回溯性能可控冗余换取性能 — 反规范化存储展示字段幂等保证可靠 — 定时任务可安全重跑异步保护体验 — 大任务不阻塞请求它不是最复杂的系统但把「业务诉求 → 数据模型 → 任务调度 → 展示层」这条链路走通且跑稳对运营决策提供了实实在在的支撑。这大概就是架构的价值——不炫技但每一处设计都有据可依。
RELATED

相关推荐

Elden Ring FPS解锁与内存补丁技术:3大核心功能深度解析与高级配置指南

Elden Ring FPS解锁与内存补丁技术:3大核心功能深度解析与高级配置指南

Elden Ring FPS解锁与内存补丁技术:3大核心功能深度解析与高级配置指南 【免费下载链接】EldenRingFpsUnlockAndMore A small utility to remove frame rate limit, change FOV, add widescreen support and more for Elden Ring 项目地址: https://gitcode.com/g…

📅 2026/10/3 21:43:23
VirtualLab Fusion | 空间光调制器像素的衍射模拟

VirtualLab Fusion | 空间光调制器像素的衍射模拟

衍射光学元件的性能受多种因素影响,其中空间光调制器(SLM)作为可编程衍射光学元件,在光束整形、全息显示等领域应用广泛。以高斯-平顶衍射光束整形器为例,SLM通过加载特定的相位调制函数来实现光束转换。然而&#xff…

📅 2026/10/3 21:43:22
《逃离塔科夫》极限猎杀战术:从游戏机制到实战,解析高价值物资获取与撤离策略

《逃离塔科夫》极限猎杀战术:从游戏机制到实战,解析高价值物资获取与撤离策略

这次我们来看一个在游戏社区中引发热议的“一秒变异”现象。它并非指某个具体的软件或模型,而是源于热门射击游戏《逃离塔科夫》中的一个极限操作瞬间。简单来说,它描述了一位玩家在极短时间内,通过击杀其他玩家,迅速集齐了游戏中…

📅 2026/9/10 3:55:07
MORE NEWS

更多资讯

📰

Kettle ETL实战:从概念原理到增量抽取与故障排查指南

简介:围绕ETL与Kettle基础主题的PPT讲解资源,面向具备一定编程基础、工作1-3年的研发人员,也适合需要在项目中独立完成数据同步与清洗的开发者。内容基于PDI9.2演示,先从ETL的抽取、转换、加载完整流程讲起,再系统拆解…

📰

AI能力操作系统:大模型时代分层调度与工程落地指南

1. 这张图不是“学习清单”,而是大模型时代的能力操作系统2026年,AI学习早已不是“学Python→学PyTorch→跑通BERT”的线性路径。我亲眼见过太多人:花三个月啃完《深度学习》、把Hugging Face所有模型都试了一遍、甚至能手写LoRA适配器&#…

📰

YOLO猫狗检测数据集实战:从标注格式到训练全流程

做目标检测的朋友应该都有过这种经历:想快速验证一个想法,结果发现光是找数据和整理标注就花了三天。尤其是猫狗识别这种看起来简单、做起来全是细节的任务,数据集的质量直接决定模型上限。最近整理了一份4300张YOLO格式的猫狗检测数据集&…

📰

Ubuntu 24.04下VTK 9.3.1交叉编译Android实战:CMake配置与链接踩坑全记录

最早接到这个任务时,我原本以为只是把桌面版的 VTK 用 CMake 交叉编译到 Android 平台,照着官方文档跑一遍就行。真正动手之后才发现,Ubuntu 24.04 配合 VTK 9.3.1 这套组合,坑点比我想象的多得多,光是解决链接期报错就…

📰

Apache NiFi 与 SNI:TLS 握手失败排查与解决指南

NiFi 跑得好好的,突然有一天某个 InvokeHTTP 处理器开始报错:"Connection reset by peer",或者日志里冒出 "unrecognized_name"。你去机房登进服务器,curl 一下目标地址完全正常,浏览器打开也正常…

📰

华为IPD流程管理核心:DCP决策与TR技术评审机制解析

简介:一份聚焦华为IPD(集成产品开发)流程管理的完整培训PPT,共96页,适合研发管理者、产品经理、项目管理及流程变革相关岗位学习,也便于企业内部导入IPD体系时作为参考课件。内容系统讲解IPD核心目标、核心…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬