Реализация расширения подтверждения для CometD в Jetty/ASP.NET

Мы используем 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 не очень хорошо документирован. Я действительно ценю любые ответы.

Ура, Крис

1 ответ

1) Это также работает с несколькими клиентами

Да, это так. Для каждого клиента выделена одна очередь сообщений (см. AcknowledgedMessagesClientExtension).

2) означает ли это, что если мой клиент не восстановится в maxInterval, сообщения все равно будут потеряны?

Да, это так. Когда клиент не может достичь сервера в течение maxInterval миллисекунд, сервер отбрасывает все состояния, связанные с этим клиентом.

2.1) Какой максимальный maxInterval? Какие последствия это должно установить его на высокое значение?

maxInterval - это параметр сервлета сервлета Cometd. Он внутренне обрабатывается как длинное значение, поэтому максимальное значение для него - 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>

Установка его в высокое значение означает, что сервер будет ждать дольше, прежде чем выбрасывать состояние, связанное с клиентом (с момента, когда клиент перестает связываться с сервером).

Я вижу две проблемы с этим. Во-первых, требования к памяти сервера могут быть выше (что также может облегчить отказ в обслуживании). Во-вторых, RemoveListener не вызывается на сервере до истечения срока действия maxInterval, что может потребовать от вас реализации дополнительной логики, которая различает "мгновенно недоступный" и "отключенный".

2.2) Нам понадобится безопасный механизм для отказов по крайней мере на несколько минут. Это возможно? Есть ли альтернативы?

Да, можно настроить maxInterval на несколько минут.

Альтернативой может быть восстановление любого состояния на стороне сервера при каждом рукопожатии. Этого можно достичь, добавив прослушиватель в "/meta/handshake" и опубликовав сообщение в канал "/service/" (чтобы убедиться, что сообщение получает только сервер), или добавив дополнительное свойство в "ext" свойство сообщения рукопожатия. Будьте внимательны, чтобы клиент мог восстановить только допустимое состояние (если необходимо, подпишите его на сервере).

3) Действительно ли необходимо только добавить два расширения как на клиенте, так и на сервере CometD?

На сервере достаточно сделать что-то вроде:

bayeux.addExtension(new AcknowledgedMessagesExtension()); 

Я не знаю, как ты это сделаешь на Оятеле. В Javascript достаточно просто включить расширение (dojo.require или script include для jQuery).

Когда клиент с AckExtension подключается к серверу, сообщение, подобное следующему, будет зарегистрировано (из моего журнала консоли Jetty):

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

Еще одно замечание, потому что это может быть неочевидно: расширение ack будет предоставлять только гарантию доставки с сервера на клиент, а не с клиента на сервер. То есть, когда вы публикуете сообщение от клиента на сервер, оно может не попасть на сервер и будет потеряно.

После того, как сообщение отправлено на сервер, расширение ack гарантирует, что все получатели, подключенные в это время, получат сообщение (если они недоступны в течение maxInterval миллисекунд).

Относительно просто реализовать повторные попытки на стороне клиента, если вы прослушиваете уведомления в "/meta/unsuccessful" и повторно отправляете сообщение (исходное сообщение, которое не удалось, передается обработчику в виде message.request).

Другие вопросы по тегам