我们使用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项目并没有得到很好的记录。我真的很感激任何答案。
干杯, 克里斯
答案 0 :(得分:1)
1)这是否适用于多个客户端
是的,确实如此。为每个客户端分配了一个消息队列(请参阅AcknowledgedMessagesClientExtension)。
2)这是否意味着如果我的客户端没有在maxInterval中恢复,那么消息仍会丢失?
是的,确实如此。当客户端无法以maxInterval毫秒到达服务器时,服务器将丢弃与该客户端关联的所有状态。
2.1)maxInterval的最大值是多少?将它设置为高值会产生哪些后果?
maxInterval是Cometd servlet的servlet参数。它在内部被视为long值,因此它的最大值是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中,它足以simply include the extension(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传递给处理程序),则实现客户端重试相对简单。