CometD 长轮询 - 它是不是可以很好地适应高流量?

Posted

技术标签:

【中文标题】CometD 长轮询 - 它是不是可以很好地适应高流量?【英文标题】:CometD long polling - Does it scale nicely to high traffic?CometD 长轮询 - 它是否可以很好地适应高流量? 【发布时间】:2014-10-05 12:40:10 【问题描述】:

如果我使用 CometD 长轮询:

假设每秒有 1000 条消息要发送给订阅者,CometD 是否允许它们自动批处理,这样每个客户端就不必为每条消息重新连接?

是否“延迟通道”(如此处所述:http://docs.cometd.org/3/reference/#_java_server_lazy_messages)在超时时自动批量发送到客户端的排队消息?

另一方面,如果我不使用惰性通道,并假设我在通道 1、2 和 3 上“批量发布”消息:

cometd.batch(function()

    cometd.publish('/channel1',  product: 'foo' );
    cometd.publish('/channel2',  notificationType: 'all' );
    cometd.publish('/channel3',  update: false );
);

(http://docs.cometd.org/3/reference/#_javascript_batch)

订阅所有 3 个频道的客户是否也批量接收它们?还是单独发送它们,强制客户端在每条消息后重新连接(慢)?

【问题讨论】:

【参考方案1】:

CometD 让应用程序开发人员可以完全控制批处理功能,从而获得最大的灵活性、性能和可扩展性。

使用 HTTP long-polling 传输时,有两个地方可能会发生批处理。

使用 CometD API 和显式批处理(如上面的 sn-p)解决了从客户端到服务器的问题。 此级别的批处理通常由应用程序控制,尽管 CometD 会进行内部批处理以避免耗尽与服务器的连接。

从服务器到客户端有更多的变化。

对于广播非延迟频道,没有自动化,通常情况下,发送给客户端(即不是发布者)的第一条消息将触发消息队列的刷新;在发送此消息时,其他消息将在该客户端的服务器端排队,并且在下一个/meta/connect 将刷新整个队列。对于 10 条消息,方案可能类似于:1-flush-9-flush(入队 1,刷新队列,在等待 /meta/connect 返回时将其他 9 入队,刷新另一个9).

对于广播惰性频道,有自动化功能,因此 CometD 将在发送 rules 惰性消息之后的这些消息之前等待。一个典型的方案可能是:10-flush

对于服务渠道,一切都在应用程序的控制之下。 客户端可以通过服务通道向应用程序发送批量消息(CometD 不会自动广播其消息)。服务器上的应用程序可以接收到第一条消息,并且知道其他 9 条消息会来,所以它可以等待发送它们,直到最后一条消息到达。当最后一个到达时,它可以使用批处理 API 将对客户端的响应进行批处理,例如:

List<ServerSession> subscribers = ...;
for (ServerSession subscriber : subscribers) 
    subscriber.batch(() -> 
        subscriber.deliver(sender, "/response", response1);
        subscriber.deliver(sender, "/response", response2);
        subscriber.deliver(sender, "/response", response3);
    );

当然,回复可能与收到的消息不同,无论是内容还是数量。 这里的方案几乎可以是应用程序想要的任何东西,但通常将其设置为 10-flush,这是最有效的。

关于批量发送回发布者的消息的说明。这是一种特殊情况,默认情况下它是自动的:在处理来自该发布者的传入消息时,CometD 为该特定发布者启动一个内部批处理,以便将传递回发布者的任何消息进行批处理,并将在传入消息的处理结束。

最重要的是,CometD 已经进行了很好的调整,可以在常见情况下提供最大的性能和可扩展性,但仍然为应用程序留有空间来自定义行为以使用特定于应用程序的消息模式知识来实现​​最大效率。

我鼓励你看看 CometD documentation, tutorials and javadocs。

【讨论】:

以上是关于CometD 长轮询 - 它是不是可以很好地适应高流量?的主要内容,如果未能解决你的问题,请参考以下文章

轮询与长轮询[关闭]

如何让spring+cometd支持websocket?

握手后,cometd立即返回“402 :: Unknown Client”错误

Ajax 长轮询限制

Cometd vs ActiveMQ 用于实时 Web 应用程序的服务器端推送

使用CometD技术实现web系统中的主动推送