↑↑↑ 欢迎 点赞、关注、收藏!!!,10 年 IT 行业老鸟,持续分享更多 IT 干货
目录
百万级会员的用户平台,如何实现快到期的会员的消息提醒?
回答
-
前提:百万级会员,这个量级不算大!!!,单表即可。
-
技术造型
-
模块 可选技术方案 分布式任务 XXL-JOB / Elastic Job 消息队列 RocketMQ(事务消息) 防重/缓存 Redis(Hash结构存储key) 数据库 MySQL(单表+索引优化)
-
1、消息推送表
推送表,参考链接:https://www.yuque.com/hollis666/go2k1v/kn7zs8zpuqeauh3g?inner=ugDmb
核心功能:
-
幂等控制(相同user_id+channel仅推送一次)
-
失败重试(阈值控制,如最多3次)
-
数据归档(定期迁移历史数据)
2、识别快到期的用户
-- 查询还有 3 天到期的用户 SELECT id FROM users WHERE expire_time BETWEEN CURDATE() + INTERVAL 3 DAY AND CURDATE() + INTERVAL 4 DAY - INTERVAL 1 SECOND;
3、如何高效查询出这些用户
分片查询
使用 XXL-JOB 的分片任务,按照用户ID进行分片。
比如,有10台机器,分表扫描尾号为0-9的用户。这样,10 台机器一起扫描这100万的数据。
SELECT id FROM users WHERE expire_time BETWEEN CURDATE() + INTERVAL 3 DAY AND CURDATE() + INTERVAL 4 DAY - INTERVAL 1 SECOND and user_id like "%0"; SELECT id FROM users WHERE expire_time BETWEEN CURDATE() + INTERVAL 3 DAY AND CURDATE() + INTERVAL 4 DAY - INTERVAL 1 SECOND and user_id like "%9";
-
参考:
优化
在上面的 SQL 中,`like "%0" 是没办法走索引的。
我们可以把 user_id 和 expire_time 建一个联合索引,让它走索引,进一步提升查询性能。
4、高效推送策略 ---- 异步推送
定时任务MQ推送服务第三方渠道消息表批量推送user_id列表消费消息批量发送(多线程)返回结果更新状态定时任务MQ推送服务第三方渠道消息表
优化点:
-
异步解耦(扫表与推送分离)
-
批量消息+多线程提升吞吐量
5、防疲劳机制
# Redis防重复推送示例 def send_notification(user_id, channel): key = f"notify:{user_id}:{channel}" if not redis.exists(key): # 发送推送 send(user_id, channel) # 设置24小时过期 redis.setex(key, 86400, 1)
特殊规则
-
配置拦截器:22:00-6:00禁止推送
-
渠道限流:短信通道QPS限制(如1000/秒)
6、异常处理
场景 | 解决方案 |
---|---|
推送失败 | 基于消息表状态重试(阈值3次) |
消息表堆积 | 归档历史数据(保留最近3个月) |
渠道故障 | 自动切换备选渠道/人工告警 |
7、优化
-
动态配置:推送频率/渠道权重通过配置中心实时调整
-
数据分析:推送表关联用户行为数据,优化推送时机
-
兜底策略:渠道异常时自动降级至站内信
↑↑↑ 欢迎 点赞、关注、收藏!!!,10 年 IT 行业老鸟,持续分享更多 IT 干货