Назад | Перейти на главную страницу

Никогда не пропустите сообщение HTTP

У меня есть веб-сервис, к которому подключено несколько "машинных" клиентов, которые время от времени отправляют данные HTTP. Природа службы такова, что я не могу позволить службе потерять ни одного входящего запроса. Однако я действительно сталкиваюсь с тем, что время от времени я получаю ошибки от бэкэнда базы данных или аналогичные, что приводит к ошибкам, и сообщение теряется. (однако ответ не так важен для доставки).

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

В настоящее время я работаю в AWS с серверной частью базы данных RDS / MySQL для веб-приложения IIS7.5. Все нагрузки сбалансированы и работают в режиме multi-az. Моя идея состоит в том, чтобы помещать любой проблемный запрос в SQS и регулярно обрабатывать эту очередь, но я предполагаю, что в этой области уже много размышлений и, вероятно, есть некоторые подводные камни, с которыми я столкнусь, если выполню его самостоятельно.

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

Если ответ на эти запросы не зависит от времени (например, это журнал, и не имеет значения, не доставляется ли журнал сразу, пока он записывается), то я определенно рассмотрю возможность использования архитектуры на основе очередей.

SQS - очевидный выбор для очередей на AWS, но имейте в виду:

  • Хотя он распределен и высокодоступен, отдельные узлы время от времени выходят из строя. Вам по-прежнему понадобится логика повторных попыток в вашем клиенте, если вы получите неисправный узел SQS.
  • SQS предоставляет только доставку "хотя бы один раз", поэтому вы можете получить сообщение более одного раза. По моему опыту, это случается редко и, по-видимому, чаще всего происходит при выходе из строя узла.

Также убедитесь, что ваша инфраструктура реплицируется в зонах доступности и, желательно, также в регионах. Ваш клиент может, например, попробовать SQS в другом регионе, если отправка в основной регион не удалась.

Очень сложно реализовать веб-сервис, который никогда не перестает обрабатывать даже один HTTP-запрос. И это, наверное, не стоит усилий. Даже если вам удастся заставить службу обрабатывать каждый запрос POST и отправлять успешный ответ, у клиента могут возникнуть другие проблемы:

  • Некое промежуточное звено между клиентом и сервером отслеживает соединение и сбрасывает его состояние.
  • Некоторый короткий период высокой потери пакетов приводит к тому, что стек TCP на клиенте прерывает соединение.
  • Время ожидания соединения истекает на уровне приложения на стороне клиента.

Все это должно обрабатываться клиентом точно так же, как и код ошибки 5xx, а именно:

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