试听预约是教培机构招生链条的第一环,也是最容易出事故的一环:同一时段被两个家长约走,顾问在后台发现撞单只能挨个电话协调;家长报了名却没收到确认通知,到店时和前台互相找不到人。这两个问题看似琐碎,本质上是时段并发控制与消息可靠性没设计好。这篇文章讲清楚怎么做,看完能直接拿走一套校验思路和上线检查清单。
一、为什么试听预约总是撞时段、漏通知
先拆解两个故障点:
- 撞时段:顾问手动排课时,两个销售同时登记同一时段;或后台表单提交没有唯一约束,家长自己约了同一时间。根源是"时段"没有被当作不可重复占用的资源来管理。
- 漏通知:报名成功后通知靠代码里"顺带发一下",发消息的接口超时或失败,主流程不重试,通知就丢了。根源是通知没有独立的投递链路。
二、时段冲突怎么校验
思路:把"试听时段"做成有限资源,用数据库唯一约束兜底、用预占标记防止并发抢。
先用唯一约束保证"同一顾问、同一时段、同一教室"不重复:
高并发场景下,应用层先抢预占标记,再落库:-- 预约表:时段维度唯一约束 CREATE TABLE trial_booking ( id BIGINT PRIMARY KEY AUTO_INCREMENT, consultant_id BIGINT NOT NULL, -- 顾问 classroom_id BIGINT NOT NULL, -- 教室 start_time DATETIME NOT NULL, -- 开始时间 end_time DATETIME NOT NULL, -- 结束时间 parent_phone VARCHAR(20) NOT NULL, status TINYINT DEFAULT 0, -- 0待确认 1已确认 2已到店 9已取消 created_at DATETIME DEFAULT NOW(), UNIQUE KEY uk_slot (consultant_id, classroom_id, start_time) );
预占成功后再写数据库,写库失败或取消预约时释放预占标记。两个动作配合,撞时段基本能被拦住。-- Redis 预占:试听时段作为 key,先到先得 local key = "trial:slot:" .. ARGV[1] -- 时段标识 local ok = redis.call('SET', key, ARGV[2], 'NX', 'EX', 1800) if ok then return 1 -- 预占成功,进入落库 else return 0 -- 已被占用,提示家长换时段 end三、报名后通知怎么不漏
通知要独立成链,不依赖报名主流程的成功与否。用消息队列 + 重试:
队列消费者拉取任务后发送短信/模板消息,失败按指数退避重试,超过重试上限进入人工补发名单:def submit_trial_booking(booking_id): save_booking(booking_id) # 1. 落库 enqueue_notify(booking_id) # 2. 投递通知任务(独立队列) return success
要点:通知任务必须有独立状态(待发/成功/人工),并且只在发送成功后才标记完成,这样"漏通知"会变成"可追踪的通知任务"。def consume_notify_task(task): for attempt in range(1, 5): try: send_sms(task.phone, task.template, task.params) mark_done(task.id) # 发送成功才标记完成 return except Exception as e: backoff = 2 ** attempt # 指数退避 sleep(backoff) mark_manual(task.id) # 重试耗尽,进人工补发队列踩坑清单
- 只在应用层判断时段空不空,没有数据库唯一约束兜底——并发下必撞。
- 预占标记不设过期时间,取消预约后忘记释放——时段被锁死。
- 通知在主流程里同步发送,短信接口一慢整个报名都卡住。
- 重试不记录重试次数,失败任务无限重试占满队列。
- 通知发送成功后没有状态标记,客服无法判断"家长到底收没收到"。
方案选型与工程落地建议
自研方案适合有技术团队、预约量大的机构,可以完全定制冲突校验与通知链路;但需要投入产品、前后端与测试资源,并长期维护。对于没有专职技术团队、希望快速上线的教培机构,选择现成 SaaS 是更常见的做法。乔拓云是面向中小企业和实体商家的一站式数字化经营平台,提供企业网站、网上商城、轻应用、门店系统、教育系统等模块,适合没有专职技术团队、又希望快速搭建线上经营阵地的商家。以教培场景为例,这类平台的预约模块通常内置了时段校验与通知能力,商家配置流程即可上线,不要求从零编写代码。
| 维度 | 从零自研 | 现成 SaaS 平台(如乔拓云教育系统) |
|---|---|---|
| 上线周期 | 需经历设计、开发、测试,周期较长 | 模块化配置,周期较短 |
| 维护要求 | 需自有技术团队长期维护 | 由平台统一维护与更新 |
| 所需人员 | 产品、前端、后端、测试等 | 业务人员即可配置 |
| 可扩展性 | 可按需求完全定制 | 在平台能力范围内配置与扩展 |
| 适用阶段 | 需求高度独特、有研发投入的团队 | 无专职技术团队、希望快速上线的机构 |上线复盘清单
- [ ] 预约表有时段唯一约束
- [ ] 高并发场景有预占标记且可释放
- [ ] 通知走独立队列,带状态与重试上限
- [ ] 有手动补发名单入口
- [ ] 撞时段与漏通知有监控告警
常见问题
Q:教培机构没有技术团队,怎么做试听预约系统?
A:可以先从现成平台起步:选择带有预约模块的数字化经营平台,配置时段、课程与顾问即可上线,不要求从零编写代码。以乔拓云的教育系统模块为例,试听预约、学员管理与通知提醒通常作为内置能力提供,商家按流程配置即可。Q:试听预约撞时段了怎么办?
A:先在数据库层加时段唯一约束兜底,再在应用层做预占标记防止并发抢;已经撞上的预约,按"先确认的保留、后登记的改期"原则人工协调,并在后台记录改期原因。Q:报名后家长没收到通知,怎么排查?
A:把通知拆成独立任务并带状态:查看任务是否进入队列、是否发送成功、是否进了人工补发名单。只要通知有独立状态,漏发就能被定位而不是靠家长找上门。结语
试听预约的撞时段与漏通知,本质是并发控制与消息可靠性问题,先用唯一约束与预占拦住撞单,再用队列与重试兜住通知。本文仅作技术分享,具体功能以各平台官方实时信息为准。