Предоставление таймаута запроса при отправке сообщения в SQS - PullRequest
1 голос
/ 19 мая 2019

Я использую SQS в своем проекте.Я хочу указать время ожидания при отправке сообщения в стандартную очередь SQS.Под тайм-аутом (не тайм-аутом видимости) я подразумеваю, что если мое сообщение не будет отправлено в SQS в течение, скажем, 200 мс, то через некоторое время я попытаюсь повторить его.Я использую API-интерфейсы JAVA для того же.

Изначально я пытался самостоятельно справиться с таймаутом, попросив задачу Callable отправить сообщение в SQS, он вернул мне будущий объект, и я ждал его, предоставив тайм-аут.Но это привело к тому, что запрос был отправлен в SQS, в то время как сообщение отправляется, мой тайм-аут вступает в силу, и до получения ответа на это уже отправленное сообщение мой код думает, что это тайм-аут из-за этого будущего объекта.

Когда я перехожу к документации по SQS, я не нахожу ничего, связанного с предоставлением тайм-аута запроса при вызове SQS push, pull или delete.

final Future<ISendMessageResult> future = timeoutHelperThreadPool.getExecutor().submit(() -> {
  return getQueueStore().sendMessage(request).get();
});
try {
  sendMessageResult = future.get(200, TimeUnit.MILLISECONDS);
  logger.info("SQS_PUSH_SUCCESSFUL");
  return true;

} catch (final TimeoutException e) {
  logger.error("SQS_PUSH_TIMEOUT_EXCEPTION");
}

Есть ли я в любом случае могуубедиться, что если я получил тайм-аут, мое сообщение не будет отправлено в SQS или наоборот?

Ответы [ 2 ]

1 голос
/ 19 мая 2019

Внутри вы можете поймать блок вы можете попробовать

catch (final TimeoutException e) {
  future.cancel(true);
  logger.error("SQS_PUSH_TIMEOUT_EXCEPTION");
}

Здесь следует отметить один момент: если сообщение уже отправлено в SQS к тому времени, когда поток прерывается, вы получите ложный отрицательный результат. Я предлагаю вам установить какое-то щедрое значение для тайм-аута

0 голосов
/ 19 мая 2019

Я бы предположил, что вы либо решаете не ту проблему, либо пытаетесь решить принципиально невозможную проблему, возможно, из-за недостаточной осведомленности о сложности базовых действий, которые происходят при отправке сообщения в SQS.

Все эти действия требуют ненулевого количества времени, и все они в некоторой степени являются переменными ...


Запрос SQS преобразуется в запрос HTTP.

Запрос подписан.

Пройдя этот этап, вы фактически обязуетесь отправить сообщение, если не произойдет сбой.

Следующие три шага могут или не могут произойти для каждого сообщения.Это зависит от того, взаимодействовали ли вы недавно со службой, что может означать, что у вас есть кэшированный ответ DNS или даже многократно используемое TCP-соединение с установленным TLS в HTTP keep-alive, ожидая следующего запроса, но это подстановочный знак.

DNS-запрос ищет конечную точку SQS.

TCP-соединение установлено с конечной точкой.

Сеанс TLS (SSL) установлен.

HTTP-запрос отправляется по проводной сети.

На данный момент вы все еще ждете, и часы все еще тикают, но теперь вы ничего не можете сделать, чтобы остановить запрособрабатываются, и еще предстоит много работы.Закрытие соединения может привести к тому, что служба прекратит обработку запроса, но нет никаких оснований ожидать, что это произойдет, поскольку служба вряд ли увидит, что соединение закрыто, пока не попытается записать ответ.... в этот момент это не имеет значения.

HTTP-запрос получен по сети.(Этот элемент указан отдельно от предыдущего элемента, поскольку передача запроса по сети также требует ненулевого периода времени.)

Служба проверяет, истек ли срок действия запроса.

Служба проверяет, правильно ли подписан запрос.

Служба проверяет, авторизован ли подписывающий пользователь выполнять запрошенное действие.

Служба фактически обрабатывает запрошенное действие.

Служба генерирует ответ.

Ответ отправляется по сети.

Ответ принимается по сети.

Ответ анализируется клиентом.


Как и в случае практически любого веб-сервиса, все становится вне вашего контроля, как только запрос поступает в пункт назначения.

tl; dr: перед лицом тайм-аута, невозможно обеспечить какой-либо уровень гарантии того, что сообщение не было отправлено.

См. также Проблема двух генералов .

ОднакоЭто одна из проблем, решаемых с помощью очередей SQS FIFO.Очереди FIFO поддерживают присвоение вами идентификатора дедупликации сообщения каждому сообщению, что позволяет вам безопасно повторить доставку сообщения в SQS в течение максимального периода 5 минут.В течение этого временного окна, если вы отправляете одно и то же сообщение в одну и ту же очередь (возможно, из-за неоднозначности, вызванной тайм-аутом), дублирующее сообщение отбрасывается службой, но в ответе сообщается, что доставка прошла успешно, поскольку... ранее.

Идентификатор дедупликации сообщения - это токен, используемый для дедупликации отправленных сообщений.Если сообщение с определенным идентификатором дедупликации сообщений отправлено успешно, любые сообщения, отправленные с тем же идентификатором дедупликации сообщений, принимаются успешно, но не доставляются в течение 5-минутного интервала дедупликации.

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagededuplicationid-property.html

...