React Native移动端通知系统开发技术咨询
解决方案与疑问解答
一、Kafka核心疑问解答
1. 消费者消费后消息是否会被删除?
不会。Kafka的消息删除逻辑和消费行为完全无关:
- 消息只会在达到主题保留策略(比如保留7天、或达到指定存储大小)时才会被清理;
- 消费者消费消息后,只是提交自己所在消费者组的偏移量(offset),标记该组已经读到这个位置,消息本身依然存在于主题中,其他消费者组可以继续读取。
2. 同一主题下如何筛选特定用户消息且不影响其他用户?
你当前“所有用户的通知发同一个主题”的思路是合理的,不需要为每个用户单独建主题,推荐以下实现方式:
- 生产者端:发送消息时,在消息内容里明确带上
recipient_user_id(接收者ID),示例消息结构:{ "recipient_user_id": 123, "notification_type": "answer", "content": "3人已回复你的问题", "meta": { "last_commenter_name": "张三", "last_commenter_avatar": "xxx.jpg", "discussion_id": 456 } } - 消费者端:
- 每个在线用户的WebSocket连接对应一个独立的消费者实例,且每个消费者的消费者组名唯一(比如
notification-consumer-${user_id}); - 用户上线时,启动该消费者,订阅
answers/views主题,从自己消费者组的最后偏移量开始消费; - 消费者每收到一条消息,先判断
recipient_user_id是否等于当前连接的用户ID:- 是:推送到对应的WebSocket连接,然后提交偏移量;
- 否:直接跳过并提交偏移量——因为你的消费者组是唯一的,这条消息不属于当前用户,但其他用户的消费者组会维护自己的偏移量,不会被影响。
- 每个在线用户的WebSocket连接对应一个独立的消费者实例,且每个消费者的消费者组名唯一(比如
这样既保证了每个用户能获取到自己的所有离线消息,又不会因为同一主题的消息互相干扰。
二、通知聚合实现
针对「多条回复更新为X人已回复」的需求,需要在后端做通知状态维护:
- 在PostgreSQL中新建
notifications表,核心字段:id(主键)user_id(接收用户ID)target_type(关联类型,比如discussion)target_id(关联ID,比如讨论ID)unread_count(未读回复数)last_commenter_id(最后评论者ID)last_commenter_avatar(最后评论者头像)content(通知内容,比如「X人已回复你的问题」)read_at(已读时间,null表示未读)created_at/updated_at
- 当有新回复时:
- 先查询是否存在该用户对应此讨论的未聚合通知(
user_id+target_id+read_at is null); - 存在:更新
unread_count +=1,更新last_commenter相关字段,更新updated_at; - 不存在:创建新通知,
unread_count=1,填充评论者信息;
- 先查询是否存在该用户对应此讨论的未聚合通知(
- 将这条聚合后的通知发送到Kafka的
answers主题。
三、实时推送与离线存储
- 前台在线时:Node.js后端维护WebSocket连接池,记录每个连接对应的
user_id;当Kafka消费者收到属于在线用户的通知时,直接从连接池中找到对应连接推送消息,同时可按需更新PostgreSQL的notifications表(比如实时标记已读)。 - 用户离线时:消息存储在Kafka主题中,只要在主题保留期内,用户下次上线启动消费者时,就能读取到所有未消费的自己的通知,推送到应用内。
四、持久化存储选择:PostgreSQL vs MongoDB
推荐沿用现有的PostgreSQL,不需要换MongoDB:
- 通知是结构化数据,需要和现有用户、讨论系统做关联查询,PostgreSQL的关系型特性更适配;
- PostgreSQL的
JSONB类型可以灵活存储通知的元数据(比如评论者头像、用户名等),兼顾结构化和灵活性; - 你现有技术栈已经熟悉PostgreSQL,切换MongoDB会增加学习和维护成本,没必要。
五、Redis vs Kafka的补充说明
你放弃Redis选Kafka是正确的:
- Redis Pub/Sub是无持久化的,用户离线时消息直接丢失,无法满足离线存储需求;
- Redis的List做消息队列的话,当用户量(12000)增大时,维护每个用户的队列会非常繁琐,且Redis的持久化不如Kafka可靠;
- Kafka的主题-分区模型天生适合处理大量用户的通知消息,且持久化、可扩展性更强。
内容的提问来源于stack exchange,提问作者Sam Leurs
相关产品推荐
相关产品推荐

