首页 文章

Build 通知系统[关闭]

提问于
浏览
170

我正在为我们的页面(社交游戏类型)构建Facebook风格的通知系统,我现在正在研究设计这种系统的最佳方式 . 我对如何向用户或类似的东西推送通知感兴趣(现在甚至) . 我正在研究如何在服务器上构建系统(如何存储通知,存储它们的位置,如何获取它们等等) .

那么......我们有一些要求:

  • 在高峰时段,我们有大约1k个并发登录用户(以及更多客人,但他们没关系,因为他们没有通知)会产生很多事件

  • 会有不同类型的通知(用户A已将您添加为朋友,用户B已对您的 Profiles 进行了评论,用户C已经喜欢您的图片,用户D已经在游戏X上击败了您,...)

  • 大多数事件将为1个用户生成1个通知(用户X喜欢您的图像),但是会有一个事件会生成许多通知的情况(例如's user Y'生日)

  • 通知应归为一组;如果例如四个不同的用户喜欢某个图像,那么该图像的所有者应该得到一个通知,说明四个用户喜欢该图像而不是四个单独的通知(就像FB一样)

好吧,我想的是我应该创建一些队列,我会在事件发生时存储它们 . 然后我会有一个后台工作(gearman?),它将查看该队列并根据这些事件生成通知 . 然后,此作业将在每个用户的数据库中存储通知(因此,如果事件影响10个用户,则会有10个单独的通知) . 然后,当用户打开包含通知列表的页面时,我会为他读取所有这些通知(我们考虑将其限制为100个最新通知)并将它们组合在一起然后最终显示它们 .

我对这种方法感到担心的事情:

  • 复杂如地狱:)

  • 数据库是这里最好的存储(我们使用MySQL)或者我应该使用别的东西(redis看起来也很合适)

  • 我应该存储什么作为通知?用户ID,发起事件的用户ID,事件类型(以便我可以对它们进行分组并显示相应的文本)但是我有点不知道如何存储通知的实际数据(例如图像的URL和 Headers )很喜欢) . 当我生成通知时,我应该只是"bake"该信息,还是应该存储受影响的记录的ID(图像,配置文件......),并在显示通知时将信息从数据库中提取出来 .
    即使我必须在显示通知页面时即时处理100个通知,

  • 性能也应该没问题

  • 每个请求都可能出现性能问题,因为我必须向用户显示未读通知的数量(由于我将通知组合在一起,这可能是一个问题) . 如果我在后台生成通知视图(它们被分组的位置)而不是即时生成,则可以避免这种情况

那么您如何看待我提出的解决方案和我的担忧?如果您认为我应该提及其他与此相关的内容,请发表评论 .

哦,我们在页面上使用PHP,但这不应该是我认为的一个重要因素 .

4 回答

  • 168

    这实际上是一个抽象的问题,所以我想我们只是要讨论它而不是指出你应该或不应该做什么 .

    以下是我对您的担忧的看法:

    • 是的,通知系统很复杂,但不是很糟糕 . 您可以在建模和实现此类系统时使用许多不同的方法,并且它们可以具有从中等到高级的复杂性;

    • Pesonally,我总是试图让数据库驱动的东西 . 为什么?因为我可以保证完全控制正在发生的一切 - 但这只是我,你可以在没有数据库驱动的方法的情况下控制;相信我,你会想要控制那个案子;

    • 让我举一个真实案例给你,所以你可以从某个地方开始 . 在过去的一年里,我已经在某种社交网络中建模并实现了一个通知系统(当然不是像facebook那样) . 我以前在那里存储通知的方式?我有一个 notifications 表,其中我保留了 generator_user_id (生成通知的用户的ID), target_user_id (显而易见,不是吗?), notification_type_id (引用具有通知类型的不同表) ),以及我们需要填充表格的所有必要的东西(时间戳,标志等) . 我的 notification_types 表曾经与 notification_templates 表有关系,它为每种类型的通知存储了特定的模板 . 例如,我有一个 POST_REPLY 类型,其模板类似于 {USER} HAS REPLIED ONE OF YOUR #POSTS . 从那里开始,我只将 {} 视为变量,将 # 视为参考链接;

    • 是,性能 shouldmust 好的当您想到通知时,您会想到服务器从头到脚推动 . 如果你打算用ajax请求或其他什么来做,你将不得不担心性能 . 但我认为这是第二次关注;

    我设计的那种模式当然不是唯一可以遵循的模式,也不是最好的模型 . 我希望我的回答至少会让你走向正确的方向 .

  • 8

    我个人对接受的答案的图表不太了解,所以我将附加一个数据库图表,基于我可以从接受的答案和其他页面中学到的东西 .

    改进很受欢迎 .

  • 4

    通知是关于某人(对象=事件,友情......)被某人(演员)改变(动词=添加,请求...)并报告给用户(主题)的通知 . 这是一个规范化的数据结构(虽然我使用过MongoDB) . 您需要通知某些用户有关更改的信息 . 所以这是每用户通知..这意味着如果涉及100个用户,则会生成100个通知 .

    ╔═════════════╗      ╔═══════════════════╗      ╔════════════════════╗
    ║notification ║      ║notification_object║      ║notification_change ║
    ╟─────────────╢      ╟───────────────────╢      ╟────────────────────╢
    ║ID           ║—1:n—→║ID                 ║—1:n—→║ID                  ║
    ║userID       ║      ║notificationID     ║      ║notificationObjectID║
    ╚═════════════╝      ║object             ║      ║verb                ║
                         ╚═══════════════════╝      ║actor               ║
                                                    ╚════════════════════╝
    

    (添加您认为合适的时间字段)

    这基本上是为每个对象分组更改,因此您可以说“您有3个朋友请求” . 每个演员的分组很有用,所以你可以说“用户James Bond在你的床上做了改变” . 这也可以根据需要翻译和计算通知 .

    但是,由于对象只是一个ID,您需要通过单独调用获取所需的所有对象的额外信息,除非对象实际更改并且您想要显示该历史记录(例如“用户将事件 Headers 更改为... “)

    由于通知对于网站上的用户来说接近实时,我会将它们与nodejs websockets客户端绑定,并将更新添加到所有侦听器时将更新推送到nodejs .

  • 27
    ╔════════════════════╗
    ║notification        ║
    ╟────────────────────╢
    ║Username            ║
    ║Object              ║
    ║verb                ║
    ║actor               ║
    ║isRead              ║
    ╚════════════════════╝
    

    这看起来是一个很好的答案,而不是有2个集合 . 您可以通过用户名,对象和isRead查询以获取新事件(例如3个待处理的朋友请求,4个问题等...)

    如果此架构存在问题,请告诉我 .

相关问题