【问题标题】:Design pattern : notification system设计模式:通知系统
【发布时间】:2010-11-21 21:46:02
【问题描述】:

我正在开发一个将使用社交网络功能的网站(例如 facebook)。

我想实现一个通知系统,它显示诸如“X 加你为朋友”、“Y 邀请你参加聚会”、“Z 参加了最新的测验”之类的内容......我不知道怎么办。

我想知道最好的解决方案是什么:

  • 解决方案 1,又称“日志记录”。

专用表“通知”。每次发生通知(添加朋友、回答测验等)时,我都会在此表中添加行。表“通知”具有包含不同信息的字段,根据添加到表中的通知类型。

:易于编码,通知功能和“普通”功能分开,当我需要阅读表格时不会消耗太多资源。

不好:通知表可能会变得非常大(我想我会在表中添加 10k 行/天),“重复”信息:通知表中的信息可以在所有其他中找到使用日期/列表/任何比较的表格。

  • 解决方案 2,又称“到处寻找”。

每次我需要显示通知列表或显示有多少新通知时,我都会查看所有相关表格,比较日期/等以了解自用户上次检查通知以来是否发生了新情况。

:与解决方案 1 相比,表格不是太大,没有“冗余”信息。

不好:我很害怕,因为用户数量(~1k+),它使服务器爆炸,因为它是资源/时间消耗,编码/维护有点困难。

你能告诉我你认为什么更好以及为什么,或者你有一个我没有想到的解决方案吗?

谢谢 =)


编辑: 假设我使用了一个非常基本的数据库设计:用户有朋友,可以做测验。

1个表格用于用户列表,测验列表,

1 表测验用户关系,

1 个表用户友谊用户。

每次用户访问自己的个人资料时,他都可以看到发生了什么:新测验用户关系,新用户用户关系等。 你会如何设计这样的通知?

【问题讨论】:

    标签: design-patterns database-design


    【解决方案1】:

    创建一个系统队列,添加到这个队列的每条消息都有一个“消费者”列表和内容。主消息泵处理每条消息并将消息发送给所有消费者。

    假设 2 个人互相成为朋友。您将一条消息添加到主系统队列中,A 是 B 的朋友,消费者都是 A 和 B。当您的消息“泵”(处理器)看到此消息时,它会将其添加到 A 的队列和 B 的队列中。所以现在用户 A 和用户 B 收到一条新消息,表明他们是朋友。反过来,每个用户都有一个消息处理器,所以当它看到一条名为“我是 [某人] 的朋友”的消息时,它会将其处理为向 A 的朋友可见的“墙”添加一个新条目,即“A 是 B 的朋友"等。

    这过于简单,但希望能展示如何使用消息队列(非常相似的系统被用作 Windows UI 框架),因此已经有一个现有的示例,并且您可以使用大量同步的消息队列模式。

    休息由你来设计。

    【讨论】:

    • 这也是我喜欢的解决方案。但我想知道包含每个用户通知的“队列”表在一段时间后是否不会太大?假设我有 2k 个用户,每天有 5 个通知(大约会发生什么),这个表中每天有 10k 个新行。你怎么看?
    • 您可以拥有“免费代理”队列,这些队列被分配给有消息待处理的用户,一旦所有消息都消失,队列可以进入空闲队列池以供其他用户使用。这也可以控制您生成更新的速度,有限的池很有用,并且监控每个队列的平均消息或等待队列中的消息可以告诉您何时需要水平扩展系统。
    • 嗯,你能不能解释的更清楚一点。在我既不是美国人也不是英国人的快速,以及我在开发方面糟糕的事实(^^)之间,我没有听懂你所说的一切。谢谢 =)
    • 我真的不擅长开发,但我也不明白。如果你能更详细地解释,最好有一个例子。
    【解决方案2】:

    这真的属于我如何设计汽车?类型的问题类别...

    实现取决于设计、未来的发展方向以及您将在其中实现的环境。您可以选择 twitter 式的实现、由 SAN 支持的 XML 系统、关系数据库、Hadoop 和大量其他系统。

    对网络技术、经验、试验和错误的充分了解是您设计任何功能的唯一方法,并且确定您正在做的是正确的(ish)方法。

    您的性能需求是什么?流量水平?用户要求?您想稍后分发(例如通过 webhook 吗?)。

    您的问题需要更具体。

    我个人会有一个“通知类型”表,就像一个枚举......然后是一个用户通知表来处理通知和用户之间的关系。

    通过一些良好的编码,您可以将用户通知表拼接到许多服务器上,并键入用户 ID 或类似内容......并在每个节点之间复制类型表以供本地缓存/参考。类似的东西。

    【讨论】:

    • 我虽然我会做这样的事情。谢谢,不知道Hadoop。
    • Clement 要求一个通用的通知模式,我认为这是一个合理的问题。
    【解决方案3】:

    我建议使用普通通知。没有通知类型或其他。

    通知
    -id
    -消息
    -href(用户点击通知时的链接)
    -receiverUser
    -日期

    示例用法: 约翰(34 岁)赞了一张玛丽(47 岁)的照片。 (我们正在向 Mary 发送通知)

    INSERT INTO Notifications(message,href,receiverUser, date) VALUES ('John liked your photo', 'link of the photo', 47, 01.11.2014) 
    

    【讨论】:

    • 如果大多数通知都相同怎么办?拥有一个包含所有可能通知消息的表格,然后在 Notifications 表格中对其使用 FK 不是更容易吗?这样您就不会在整个数据库中重复数百万次字符串“您现在是 的朋友”。
    【解决方案4】:

    AWS 和 Azure 等服务正在提供通知框架。如果您使用其中任何一个,那么您可能无需担心表结构。您只需要从应用程序的不同点触发通知即可。

    例如,当一个用户喜欢另一个用户的某样东西时,您的应用程序可以触发一个发送事件(可以通过一个 API 调用发送给数千个用户)。 API 将存储记录并将其转发给目标用户。

    这对我们有好处。

    希望这有助于其他寻找类似解决方案的人。

    【讨论】:

      【解决方案5】:

      我所做的是建立一个专门的服务来存储以下数据:

      • recipent_id
      • actor_id
      • html_msg
      • 元数据
      • if_seen
      • 时间戳

      如果用户在线,则向 UI 发送 Socket 推送

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-18
        • 2020-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-17
        相关资源
        最近更新 更多