背景
我有一个独石Node.js + PostgreSQL应用程序,除了其他事情,需要提供实时的应用程序内通知给最终用户。
目前以下列方式实施:
- 存在DB表X1 M0 N1 X,其具有X1 M1 N1 X(未决/已发送)、X1 M2 N1 X(通知接收者的ID)、X1 M3 N1 X(用户是否读取了通知)、X1 M4 N1 X和X1 M5 N1 X-通知数据。
- 一旦创建了特定的资源或发生了特定的事件,就会有不同数量的用户收到应用程序内通知。创建通知后,通知会保存到数据库中,并使用WebSockets发送给用户。通知也可以通过cron作业创建。
- 当一个用户收到N个相同类型的通知时,它们被折叠成一个单一的通知。2这是通过数据库触发器删除重复的通知并插入一个新的来完成的。
- 通常它工作得很好。但是当接收者的数量超过几千个时,应用程序会滞后,或者其他请求会被阻止,或者不是所有的通知都会通过WebSockets发送。
通知示例 - 文章已发布
- 用户获得点数奖励
- 用户多次登录但未执行某些操作
- 一个用户向另一个用户发送好友请求
- 一个用户向另一个用户发送消息
- 如果用户接收到3+ x1M6 N1 x通知,则它们被折叠成x1M7 N1 x通知(如果接收到新的相同通知,则x1M8 N1 x被更新)。
我目前所拥有的似乎不是很好。例如,对于Article created
事件,处理创建的api端点也处理通知发送(这可能不是一个好方法-它创建了~5- 6 k的通知,并通过websockets将它们发送给用户)。
问题
如何正确设计这样的功能?
我应该继续使用node.js + db还是添加一个队列服务?Redis Pub/Sub?RabbitMQ?
我们部署到k8s集群,所以添加另一个服务不是问题。更重要的问题是-在我的情况下真的需要它吗?
我想在这个主题上阅读一些一般性的建议或资源。
我读过几篇关于消息/队列/通知系统设计的文章,但仍然不太明白这是否适合我的情况。
应该将通知存储在队列中还是存储在数据库中?实时通知数千用户的正确方法是什么(websockets?SSE?)?
而且,我读的关于队列和消息代理的内容越多,就越觉得我把事情弄得过于复杂,越来越困惑。
1条答案
按热度按时间2ul0zpep1#
考虑使用Temporal open source project。它允许将每个用户生命周期建模为一个单独的程序。Temporal使代码具有完全的容错性,并在进程重新启动时保留其完整状态(包括局部变量和阻塞等待调用)。