build立通知系统
我正在为我们的页面(社交游戏types)构buildFacebook风格通知系统,现在我正在研究devise此类系统的最佳方式。 我不知道如何推送通知给用户或类似的东西(现在甚至)。 我正在研究如何在服务器上构build系统(如何存储通知,在哪里存储它们,如何获取它们等)。
所以…我们有一些要求:
- 在高峰时间,我们有大约1k个并发login用户(还有更多的客人,但是他们在这里并不重要,因为他们不会有通知),这会产生许多事件
- 会有不同types的通知(用户A添加了你作为朋友,用户B评论了你的个人资料,用户C喜欢你的形象,用户D在游戏X上击败了你,…)
- 大多数事件会为1个用户生成1个通知(用户X已经喜欢您的图片),但是会有一个事件会生成很多通知的情况(例如用户Y的生日)
- 通知应该组合在一起; 如果像一些图像这样的四个不同的用户,该图像的所有者应该得到一个通知,说明四个用户喜欢图像,而不是四个单独的通知(就像FB一样)
好的,所以我在想,我应该创build一个队列,在事件发生的时候存储事件。 然后,我会有一个后台工作( gearman ?),看看这个队列,并根据这些事件生成通知。 这个工作然后将通知存储在每个用户的数据库中(所以如果一个事件影响10个用户,将会有10个单独的通知)。 然后,当用户打开一个包含通知列表的页面时,我会阅读所有这些通知(我们正在考虑将其限制为100个最新通知),并将它们组合在一起,然后显示出来。
我很关心这个方法:
- 复杂的地狱:)
- 是数据库最好的存储在这里(我们正在使用MySQL),或者我应该使用别的东西(redis似乎也是一个很好的适合)
- 我应该存储什么作为通知? 用户ID,发起事件的用户ID,事件types(以便我可以将它们分组并显示适当的文本),但是我不知道如何存储通知的实际数据(例如,图像的URL和标题被喜欢)。 我应该在生成通知时“烘烤”这些信息,还是应该存储受影响的logging(图像,configuration文件,…)的ID,并在显示通知时将信息从数据库中拉出。
- 性能应该可以在这里,即使我不得不在显示通知页面时dynamic处理100个通知
- 每个请求可能的性能问题,因为我将不得不向用户显示未读通知的数量(这可能是一个问题,因为我会将通知分组在一起)。 这可以避免,虽然如果我在后台,而不是即时生成的通知(他们在哪里分组)的视图
那么您对我提出的解决scheme和我的担忧有什么看法? 如果您认为我应该提及其他与此相关的内容,请发表评论。
哦,我们正在使用PHP作为我们的页面,但这不应该是我认为的一个重要因素。
通知是关于被某人(演员)改变(动词=添加,请求…)的东西(对象=事件,友谊…)并报告给用户(主题)。 这是一个规范化的数据结构(尽pipe我已经使用了MongoDB)。 您需要通知某些用户有关更改。 所以这是每个用户的通知..这意味着如果有100个用户参与,你会产生100个通知。
╔═════════════╗ ╔═══════════════════╗ ╔════════════════════╗ ║notification ║ ║notification_object║ ║notification_change ║ ╟─────────────╢ ╟───────────────────╢ ╟────────────────────╢ ║ID ║—1:n—→║ID ║—1:n—→║ID ║ ║userID ║ ║notificationID ║ ║notificationObjectID║ ╚═════════════╝ ║object ║ ║verb ║ ╚═══════════════════╝ ║actor ║ ╚════════════════════╝
(添加时间字段,你认为合适的)
这基本上是对每个对象进行分组更改,以便您可以说“您有3个朋友请求”。 每个演员的分组是有用的,所以你可以说“用户詹姆斯·邦德在你的床上做了改变”。 这也使得能够翻译和计数通知,只要你喜欢。
但是,因为对象只是一个ID,你需要获得所有额外的信息关于对象,你想与不同的调用,除非对象实际上改变,你想显示该历史(例如“用户更改事件标题… “)
由于通知接近实时的网站上的用户,我将他们与nodejs + websockets客户端与PHP推送更新到nodejs为所有听众添加更改。
这真是一个抽象的问题,所以我想我们只是要讨论它,而不是指出你应该做什么,不应该做什么。
以下是我对你的担忧的看法:
-
是的,通知系统是复杂的,但不是地狱。 在build模和实施这样的系统时可以有许多不同的方法,并且可以具有从中等到高级的复杂性;
-
Pesonally,我总是试图做的东西数据库驱动。 为什么? 因为我可以保证对所发生的一切有完全的控制 – 但是这只是我自己,你可以在没有数据库驱动的情况下进行控制; 相信我,你要控制这个案子;
-
让我举个例子给你一个真实的例子,所以你可以从某个地方开始。 在过去的一年中,我在某种社交networking(当然不是脸谱网)中build立和实施了一个通知系统。 我用来存储通知的方式? 我有一个
notifications
表,在那里我保留了generator_user_id
(生成通知的用户的ID),target_user_id
(显而易见,不是吗?),notification_type_id
(引用具有通知types的不同表)以及所有必要的东西,我们需要填写我们的表格(时间戳,标志等)。 我的notification_types
表用来和notification_types
表有关系,为每种types的通知存储特定的模板。 例如,我有一个POST_REPLY
types,它有一个类似{USER} HAS REPLIED ONE OF YOUR #POSTS
的模板,已经{USER} HAS REPLIED ONE OF YOUR #POSTS
。 从那里开始,我只把{}
当作一个variables,将#
作为参考链接。 -
是的,性能应该也是一定要好的。 当你想到通知时,你会想到从头到脚的服务器推送。 或者如果你打算用Ajax请求或其他方式来做,你将不得不担心性能。 但我认为这是第二次关注。
我devise的这个模型当然不是唯一可以遵循的模型,也不是最好的模型。 我希望我的回答至less能跟着你走向正确的方向。
╔════════════════════╗ ║notification ║ ╟────────────────────╢ ║Username ║ ║Object ║ ║verb ║ ║actor ║ ║isRead ║ ╚════════════════════╝
这看起来是一个很好的答案,而不是有2个集合。 你可以查询用户名,对象和isRead获取新的事件(如3待处理的朋友请求,4个问题等)
让我知道这个模式是否有问题。