代码之家  ›  专栏  ›  技术社区  ›  Bozho

JMS(或任何消息传递解决方案)是否适用于跟随者/跟随者模型

  •  5
  • Bozho  · 技术社区  · 14 年前

    为了简单起见,让我们假设我正在克隆twitter(我不是)。所以每个用户都可以跟随其他用户,并且被其他用户跟随。对于你关注的每个用户,你都会收到他发送的所有推文。所有内容都存储在数据存储器中(无论是NoSQL解决方案还是分片关系数据库)。

    正在联机

    • 当用户注册(或登录)时,会创建一个以他(或他的id)命名的JMS主题
    • 当用户登录时,他订阅了他所关注的每个用户的JMS主题
    • 会话范围的对象(每个用户)充当JMS消息侦听器
    • UI是通过ajax轮询会话范围的对象来更新的

    据称,这背后的想法是为了提高性能,即不要过于频繁地查询数据存储,而是在内存中缓存即时的内容。

    当然,整个过程都需要在集群中运行,并且是可伸缩的。

    • 这是否值得(在性能和可伸缩性方面)

    在某个时候(当事情是功能性的时候),我会做一些基准测试,但我想听听一些初步的评论。

    2 回复  |  直到 14 年前
        1
  •  3
  •   skaffman    14 年前

    听起来很合理。您需要确保您选择的JMS实现支持可能非常多的主题—并不是所有的主题都可以优雅地做到这一点。

    我的主要设计问题是,当用户第一次登录时,他的消息会话存储将是空的,您必须等待它填满。那么你就不需要访问数据库了,或者这不是一个问题。

    另外,这里并没有真正利用JMS的事件驱动特性。从主题接收到的消息只是转储到会话存储中,以便以后检索。

    因为它不是真正的事件驱动,所以您可以考虑使用分布式内存数据存储,例如EhCache+JGroups或JBossCache3(我强烈推荐)。新的tweet将被放到这个分布式商店中,读者只需在上面搜寻感兴趣的东西。这可能更节省内存,因为每个节点上只存储一个tweet副本。您还可以在系统启动时预加载缓存。

        2
  •  1
  •   Chris Lercher    14 年前

    其中一个因素是,用户下次登录时会看到什么:

    1. 所有在用户之前的会话中没有传递给用户的tweet。或者
    2. 之前x小时内发布的所有推文。

    案例1:JMS很好,因为队列可以记住哪些消息已经传递。但是等等:这意味着,每条消息必须有一个队列 接受者 .

    发件人 ,并使超过x小时的邮件过期。同样,JMS可能是一个不错的选择。

    性能

    JMS实现通常可以将消息保存在内存中,要访问队列/主题中的消息,您不必在大型索引中搜索—因此我假设,这应该比数据库快,可能比内存中的数据库还要快。当节点发生故障时,您可以从备份数据库重新创建队列,也可以使用 high-availability persistence 内置到一些JMS实现中。

    但我完全同意skaffman的观点:与分布式内存数据存储相比,您将使用更多的内存。JMS的优点是,它简化了消息的自动过期(以及其他一些事情),我不知道重新实现该功能是否是个好主意。

    所以也许我要做的,就是把id保存在队列中,把实际的消息保存在Java对象缓存中。这样,您将再次不得不使用索引,但是您可以从JMS获得便利,并获得对象缓存的大部分内存效率。当缓存仅位于发送方一侧时,它甚至不必被分发,假设来自一个发送方的所有消息都驻留在一个(复制的)节点上—但这可能取决于许多其他体系结构决策。