婚恋系统的续费提醒为什么总漏单:节点表、去重与订阅消息配额

📅 发布时间:2026/10/14 9:21:31
婚恋系统的续费提醒为什么总漏单:节点表、去重与订阅消息配额
月底对账老板发现三个会员的合同过期半个多月了续费的钱一分没进来。问红娘红娘说我以为您那边盯着呢。两个人都以为对方在盯结果是没人盯。这不是态度问题是婚恋系统没把节点接住。一个红娘手上同时跟着二三十个会员每个人的服务周期、回访节点、材料补交时间都不一样旺季会员量一翻倍漏是必然的。人的记忆上限摆在那靠我脑子里有数撑不住。所以婚恋系统里真正值钱的模块之一不是匹配算法是把什么时候该干什么这件事从红娘脑子里搬出来的提醒引擎。听起来简单我们做的时候踩的坑不少这篇文章把节点表设计、扫描去重和订阅消息触达这几段拆开讲。把节点从脑子里搬进一张表婚恋系统的节点表设计第一步是想清楚提醒的不是会员快到期这一个事件而是一串服务节点。婚介服务的实际流程里至少有这几类节点值得钉住合同到期前 30 天谈续费方案、服务中期做一次回访、材料齐了约见面、见面后 48 小时内收集反馈。婚恋系统如果只做到期提醒一个字段红娘很快会发现它只会催收钱别的全靠她记工具就用不起来。所以我们的节点表是规则驱动的一条规则描述什么事件发生前后、提前多少天、提醒谁CREATETABLEservice_node(idBIGINTUNSIGNEDAUTO_INCREMENTPRIMARYKEY,member_idBIGINTUNSIGNEDNOTNULLCOMMENT会员,node_typeVARCHAR(32)NOTNULLCOMMENTrenew/followup/material/feedback,trigger_dayDATENOTNULLCOMMENT节点日期,offset_daysINTNOTNULLDEFAULT0COMMENT提前提醒天数,owner_idBIGINTUNSIGNEDNOTNULLCOMMENT负责红娘,statusTINYINTNOTNULLDEFAULT0COMMENT0待办 1完成 2失效,created_atDATETIMENOTNULLDEFAULTCURRENT_TIMESTAMP,KEYidx_trigger(status,trigger_day,offset_days))ENGINEInnoDBDEFAULTCHARSETutf8mb4;这里有个反直觉的设计trigger_day存的是节点本身的日期提醒日是查询时用trigger_day - offset_days算出来的不单独存。原因是业务方经常改策略——这周把续费提醒从提前 30 天调成提前 45 天如果提醒日落在数据里就得批量回刷存量数据放在查询时算改配置只改一行。节点从哪来大部分不是人工录的。会员签约时按套餐规则批量生成回访节点在上一次见面完成后自动排下一次这样红娘只在异常情况下补录表的完整性才有保证。人工补的节点越多婚恋系统越退化成一本电子台账。婚恋系统的扫描是条 SQL 的事但重跑不能重发每天早上七点跑一次扫描任务把今天该提醒的节点捞出来推给对应红娘。SQL 本身很朴素SELECTid,member_id,node_type,owner_idFROM service_nodeWHEREstatus0ANDtrigger_dayBETWEENCURDATE()INTERVAL1DAYANDCURDATE()INTERVAL1DAYINTERVALoffset_days DAYLIMIT500;真正的问题在执行侧。定时任务总会因为发布重启、机器故障漏跑一次然后你补一个手动重跑入口——重跑的时候昨天已经推过的提醒绝不能再推一遍。红娘一天收到两条张姐会员下周到期第二次她就不看这个面板了狼来了效应比漏提醒更伤工具的信用。我们的做法是加一张发送流水表用唯一索引兜底CREATETABLEnode_notify_log(idBIGINTUNSIGNEDAUTO_INCREMENTPRIMARYKEY,node_idBIGINTUNSIGNEDNOTNULL,notify_dateDATENOTNULL,channelVARCHAR(16)NOTNULLCOMMENTwx/sms/inapp,sent_atDATETIMENOTNULLDEFAULTCURRENT_TIMESTAMP,UNIQUEKEYuk_node_date(node_id,notify_date,channel))ENGINEInnoDBDEFAULTCHARSETutf8mb4;推送前先INSERT IGNORE这张表插得进去才发插不进去说明今天这个节点在这个渠道已经发过了。重跑、并发、多实例部署全部被这一个唯一索引挡住。比在应用层加分布式锁简单得多而且天然带了发送记录排查红娘说没收到时直接查表。订阅消息的一次性授权是最容易翻车的地方婚恋系统里提醒怎么到红娘手上站内信没人看短信一条几分钱还容易被当垃圾拦截最顺的路是微信小程序的订阅消息。但它有个新手必踩的坑小程序订阅消息是一次性授权——用户点一次允许你只能发一条发完额度就没了。婚恋系统里的提醒是天天发的这意味着授权额度是持续消耗品。如果只在红娘第一次打开小程序时请求一次授权第二周额度就耗光了后面所有提醒都会静默失败而且你这边看到的是发送成功红娘那边什么都没收到。我们在实际项目中观察到示例数据不做额度管理时订阅消息的实际到达率在第二周后掉到两成以下做了下面的机制后稳定在八成上下。做法是三件事额度记账。每次发送前查额度发一条扣一条把微信侧的授权当成账户余额来管低于阈值就在红娘下次打开小程序时补请求授权。选对请求时机。不要在启动页弹授权红娘会条件反射点拒绝。在她刚完成一次标记节点完成的操作后弹这个时刻她刚体会到提醒的价值授权通过率明显更高示例数据约 3 倍于启动页。多渠道降级。额度不足时降级到站内信加工作台红点绝不让提醒因为单渠道失败而丢。渠道可以降节点不能丢。另外别忘了发送失败的重试要和上面那张流水表配合重试只重发失败记录且仍走唯一索引避免重试风暴变成重复轰炸。复盘提醒引擎的价值在不漏不在智能这套东西没有任何高深技术一张节点表、一条扫描 SQL、一张流水表、一个额度账本。但婚恋系统上线后示例数据婚介机构的续费节点遗漏率从每月 5 单左右降到基本归零红娘的用法也很稳定——每天早上打开工作台看一遍今日待办照着清单打电话。回头看最容易犯的错是把提醒做成通知轰炸机什么节点都推、一天推五遍、渠道不管额度。工具的信用是靠每次响都值得看攒出来的。宁可少提醒不能发噪音宁可降级到红点不能静默丢失。这两条原则比任何调度框架选型都重要。下一篇打算聊聊节点完成后反馈怎么回流让见面 48 小时收集反馈这类节点不是提醒完就结束而是真能催出一笔回访记录。文中方案来自我们在婚恋行业 SaaS云中红线的一线实践欢迎交流。