1

我们正在使用 CometD 2 来实现中央数据提供者和多个使用数据的后端之间的连接。到目前为止,当其中一个后端出现短暂故障时,在此期间发布的所有消息都会丢失。现在我们听说了 CometD 的“确认扩展”。它应该创建一个服务器端消息列表,并在其中一个客户端报告重新联机时传递它们。这里有一些问题:

1)这是否也适用于多个客户?

2)文档(http://cometd.org/documentation/2.x/cometd-ext/ack)说:“请注意,如果断开连接的浏览器断开连接的时间超过 maxInterval(默认 10 秒),那么客户端将超时并丢弃未确认的队列。” -> 这是否意味着如果我的客户端没有在 maxInterval 内恢复,消息还是会丢失?

因此,2.1) 最大的 maxInterval 是多少?将其设置为高值有什么后果?

2.2) 我们需要一个安全的机制来解决至少几分钟的故障。这可能吗?有没有其他选择?

3)真的只需要在客户端和cometD服务器中都添加这两个扩展吗?我们将 Jetty 用于服务器,将 .NET Oyatel 用于客户端。有没有人有这方面的经验?

对于这一系列问题,我很抱歉,但不幸的是,CometD 项目并没有很好的文档记录。我真的很感激任何答案。

干杯,克里斯

4

1 回答 1

1

1)这是否也适用于多个客户

是的,它确实。为每个客户端分配一个消息队列(请参阅 AcknowledgedMessagesClientExtension)。

2)这是否意味着如果我的客户端没有在 maxInterval 内恢复,消息无论如何都会丢失?

是的,它确实。当客户端在 maxInterval 毫秒内无法到达服务器时,服务器将丢弃与该客户端关联的所有状态。

2.1) 最大的 maxInterval 是多少?将其设置为高值有什么后果?

maxInterval 是Cometd servlet的一个 servlet 参数。它在内部被视为长值,因此它的最大值是 Long.MAX_VALUE。

示例配置:

<init-param>
    <!-- The max period of time, in milliseconds, that the server will wait for
         a new long poll from a client before that client is considered invalid
         and is removed -->
    <param-name>maxInterval</param-name>
    <param-value>10000</param-value>
</init-param>

将其设置为较高的值意味着服务器在丢弃与客户端关联的状态之前将等待更长的时间(从客户端停止联系服务器的时间开始)。

我看到这有两个问题。首先,服务器的内存要求可能会更高(这也可能使拒绝服务更容易)。其次,在 maxInterval 到期之前不会在服务器上调用 RemoveListener,这可能需要您实现额外的逻辑来区分“暂时无法访问”和“断开连接”。

2.2) 我们需要一个安全的机制来解决至少几分钟的故障。这可能吗?有没有其他选择?

是的,可以将 maxInterval 配置为持续几分钟。

另一种方法是在每次握手时恢复任何服务器端状态。这可以通过向“/meta/handshake”添加侦听器并将消息发布到“/service/”通道(以确保只有服务器接收消息)或向“ext”添加附加属性来实现握手消息的属性。小心让客户端只恢复有效状态(如果必须在服务器上签名)。

3)真的只需要在客户端和cometD服务器中都添加这两个扩展吗?

在服务器上,执行以下操作就足够了:

bayeux.addExtension(new AcknowledgedMessagesExtension()); 

我不知道你会如何在 Oyatel 上做到这一点。在 Javascript 中,只需包含扩展名(dojo.require 或 jQuery 的脚本包含)就足够了。

当带有 AckExtension 的客户端连接到服务器时,将记录类似于以下的消息(来自我的 Jetty 控制台日志):

[qtp959713667-32] INFO  org.cometd.server.ext.AcknowledgedMessagesExtension  - Enabled message acknowledgement for client 51vkuhps5qgsuaxhehzfg6yw92

另一个注意事项,因为它可能并不明显:ack 扩展只会提供服务器到客户端的传递保证,而不是客户端到服务器。也就是说,当你从客户端向服务器发布消息时,它可能无法到达服务器,会丢失。

一旦消息到达服务器,ack 扩展将确保当时连接的所有收件人都将收到消息(只要它们在 maxInterval 毫秒内不可达)。

如果您在“/meta/unsuccessful”上收听通知并重新发送消息(失败的原始消息作为 message.request 传递给处理程序),则实现客户端重试相对简单。

于 2012-03-11T15:13:36.380 回答